Return content with IHttpActionResult for non-OK response

C#asp.net Web-ApiHttpresponse

C# Problem Overview


For returning from a Web API 2 controller, I can return content with the response if the response is OK (status 200) like this:

    public IHttpActionResult Get()
    {
        string myResult = ...
        return Ok(myResult);
    }

If possible, I want to use the built-in result types here when possible: https://msdn.microsoft.com/en-us/library/system.web.http.results(v=vs.118).aspx

My question is, for another type of response (not 200), how can I return a message (string) with it? For example, I can do this:

    public IHttpActionResult Get()
    {
       return InternalServerError();
    }

but not this:

    public IHttpActionResult Get()
    {
       return InternalServerError("Message describing the error here");
    }

Ideally I want this to be generalized so that I can send a message back with any of the implementations of IHttpActionResult.

Do I need to do this (and build my own response message):

    public IHttpActionResult Get()
    {
       HttpResponseMessage responseMessage = ...
       return ResponseMessage(responseMessage);
    }

or is there a better way?

C# Solutions


Solution 1 - C#

You can use this:

return Content(HttpStatusCode.BadRequest, "Any object");

Solution 2 - C#

You can use HttpRequestMessagesExtensions.CreateErrorResponse (System.Net.Http namespace), like so:

public IHttpActionResult Get()
{
   return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Message describing the error here"));
}

It is preferable to create responses based on the request to take advantage of Web API's content negotiation.

Solution 3 - C#

I ended up going with the following solution:

public class HttpActionResult : IHttpActionResult
{
    private readonly string _message;
    private readonly HttpStatusCode _statusCode;

    public HttpActionResult(HttpStatusCode statusCode, string message)
    {
        _statusCode = statusCode;
        _message = message;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage(_statusCode)
        {
            Content = new StringContent(_message)
        };
        return Task.FromResult(response);
    }
}

... which can be used like this:

public IHttpActionResult Get()
{
   return new HttpActionResult(HttpStatusCode.InternalServerError, "error message"); // can use any HTTP status code
}

I'm open to suggestions for improvement. :)

Solution 4 - C#

You can also do:

return InternalServerError(new Exception("SOME CUSTOM MESSAGE"));

Solution 5 - C#

Simple:

return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Your message"));

Remember to reference System.Net.Http and System.Net.

Solution 6 - C#

Anyone who is interested in returning anything with any statuscode with returning ResponseMessage:

//CreateResponse(HttpStatusCode, T value)
return ResponseMessage(Request.CreateResponse(HttpStatusCode.XX, object));

Solution 7 - C#

In ASP.NET Web API 2, you can wrap any ResponseMessage in a ResponseMessageResult:

public IHttpActionResult Get()
{
   HttpResponseMessage responseMessage = ...
   return new ResponseMessageResult(responseMessage);
}

In some cases this may be the simplest way to get the desired result, although generally it might be preferable to use the various results in System.Web.Http.Results.

Solution 8 - C#

I would recommend reading this post. There are tons of ways to use existing HttpResponse as suggested, but if you want to take advantage of Web Api 2, then look at using some of the built-in IHttpActionResult options such as

return Ok() 

or

return NotFound()

Choose the right return type for Web Api Controllers

Solution 9 - C#

A more detailed example with support of HTTP code not defined in C# HttpStatusCode.

public class MyController : ApiController
{
    public IHttpActionResult Get()
    {
        HttpStatusCode codeNotDefined = (HttpStatusCode)429;
        return Content(codeNotDefined, "message to be sent in response body");
    }
}

Content is a virtual method defined in abstract class ApiController, the base of the controller. See the declaration as below:

protected internal virtual NegotiatedContentResult<T> Content<T>(HttpStatusCode statusCode, T value);

Solution 10 - C#

Below code / class really helpful to handle all type of responses. May be success or fail etc.

Why should I use this? :

Suppose I am consuming web API service. There are some possibilities of output as below:

  1. You might not get any result because of validation error
  2. You will get expected result
  3. You will get error.

So here I have solution to handle all the scenarios. Also I tried to maintain uniformity in the output. You can give remark or actual error message. The web service consumer can only check IsSuccess true or not else will sure there is problem, and act as per situation. There should be perfect communication between web API developer and web API consumer. If result is not generating then why. The comment or exception will acknowledge and they will act accordingly. Hence this is best solution for web API consumer / user.

Single response for all all type of results.

  public class Response
    {
        /// <summary>
        /// Gets or sets a value indicating whether this instance is success.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is success; otherwise, <c>false</c>.
        /// </value>
        public bool IsSuccess { get; set; } = false;
    
        /// <summary>
        /// Actual response if succeed 
        /// </summary>
        /// <value>
        /// Actual response if succeed 
        /// </value>
        public object Data { get; set; } = null;
    
        /// <summary>
        /// Remark if anythig to convey
        /// </summary>
        /// <value>
        /// Remark if anythig to convey
        /// </value>
        public string Remark { get; set; } = string.Empty;
        /// <summary>
        /// Gets or sets the error message.
        /// </summary>
        /// <value>
        /// The error message.
        /// </value>
        public object ErrorMessage { get; set; } = null;
    
       
    }  
    



[HttpGet]
        public IHttpActionResult Employees()
        {
            Response _res = new Response();
            try
            { 
                DalTest objDal = new DalTest(); 
                _res.Data = objDal.GetTestData();
                _res.IsSuccess = true;
                return Request.CreateResponse(HttpStatusCode.OK, _res);
            }
            catch (Exception ex)
            {
                _res.IsSuccess = false;
                _res.ErrorMessage = ex;
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.InternalServerError, _res )); 
            } 
        }

You are welcome to give suggestion if any :)

I am happy if anyone is using and get benefited. Write me if any addition or modification makes this more improved, on [email protected].

Solution 11 - C#

@mayabelle you can create IHttpActionResult concrete and wrapped those code like this:

public class NotFoundPlainTextActionResult : IHttpActionResult
{
    public NotFoundPlainTextActionResult(HttpRequestMessage request, string message)
    {
        Request = request;
        Message = message;
    }

    public string Message { get; private set; }
    public HttpRequestMessage Request { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(ExecuteResult());
    }

    public HttpResponseMessage ExecuteResult()
    {
        var response = new HttpResponseMessage();

        if (!string.IsNullOrWhiteSpace(Message))
            //response.Content = new StringContent(Message);
            response = Request.CreateErrorResponse(HttpStatusCode.NotFound, new Exception(Message));

        response.RequestMessage = Request;
        return response;
    }
}

Solution 12 - C#

I had the same problem. I want to create custom result for my api controllers, to call them like return Ok("some text");

Then i did this:

  1. Create custom result type with singletone

    public sealed class EmptyResult : IHttpActionResult { public Task ExecuteAsync(CancellationToken cancellationToken) { return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.NoContent) { Content = new StringContent("Empty result") }); } }

  2. Create custom controller with new method:

    public class CustomApiController : ApiController { public IHttpActionResult EmptyResult() { return new EmptyResult(); } }

And then i can call them in my controllers, like this:

public IHttpActionResult SomeMethod()
    {
       return EmptyResult();
    }

Solution 13 - C#

this answer is based on Shamil Yakupov answer, with real object instead of string.

using System.Dynamic;

dynamic response = new ExpandoObject();
response.message = "Email address already exist";

return Content<object>(HttpStatusCode.BadRequest, response);

Solution 14 - C#

For exceptions, I usually do

 catch (Exception ex)
        {
            return InternalServerError(new ApplicationException("Something went wrong in this request. internal exception: " + ex.Message));
        }

Solution 15 - C#

Sorry for the late answer why don't you simple use

return BadRequest("your message");

I use it for all my IHttpActionResult errors its working well

here is the documentation : https://msdn.microsoft.com/en-us/library/system.web.http.apicontroller.badrequest(v=vs.118).aspx

Solution 16 - C#

You can use this:

return BadRequest("No data is present in table!!");

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmayabelleView Question on Stackoverflow
Solution 1 - C#Shamil YakupovView Answer on Stackoverflow
Solution 2 - C#user1620220View Answer on Stackoverflow
Solution 3 - C#mayabelleView Answer on Stackoverflow
Solution 4 - C#ilansView Answer on Stackoverflow
Solution 5 - C#Rodrigo ReisView Answer on Stackoverflow
Solution 6 - C#CularBytesView Answer on Stackoverflow
Solution 7 - C#sfuquaView Answer on Stackoverflow
Solution 8 - C#wegunterjrView Answer on Stackoverflow
Solution 9 - C#themefieldView Answer on Stackoverflow
Solution 10 - C#Amol KhandagaleView Answer on Stackoverflow
Solution 11 - C#Quoc NguyenView Answer on Stackoverflow
Solution 12 - C#MerchezatterView Answer on Stackoverflow
Solution 13 - C#Kugan KumarView Answer on Stackoverflow
Solution 14 - C#ahsantView Answer on Stackoverflow
Solution 15 - C#benraayView Answer on Stackoverflow
Solution 16 - C#Nilam DesaiView Answer on Stackoverflow