Return content with IHttpActionResult for non-OK response

272,305

Solution 1

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 2

You can use this:

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

Solution 3

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 4

You can also do:

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

Solution 5

Simple:

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

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

Share:
272,305

Related videos on Youtube

mayabelle
Author by

mayabelle

I am a full-time mid-level web and application developer working in all application layers, with experience primarily in C#/.NET, MVC, MS SQL/T-SQL, JavaScript/JQuery/AJAX, CSS, HTML5, LINQ, HTTP, Visual Studio, TFS, and more.

Updated on July 15, 2022

Comments

  • mayabelle
    mayabelle almost 2 years

    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?

    • Milen
      Milen over 9 years
    • Ric
      Ric over 9 years
      could you not use ApiController.InternalServerError msdn.microsoft.com/en-us/library/dn292630(v=vs.118).aspx
    • mayabelle
      mayabelle over 9 years
      @Milen, Thank you. Something like that might work. The part I don't like is it requires creating a different IHttpActionResult implementation for each existing implementation I want to be able to use.
    • mayabelle
      mayabelle over 9 years
      @Ric, no, the parameter is an Exception. I want to set a message as a string. Also, this doesn't address a more general case where the code might not necessarily be internal server error.
    • Isaac
      Isaac almost 8 years
      @mayabelle: Did you see Shamil Yakupov`s answer? It's much simpler and concise that the accepted answer.
  • mayabelle
    mayabelle over 9 years
    Request.CreateErrorResponse returns an HttpResponseMessage, not IHttpActionResult. What you describe is good practice for creating an HttpResponseMessage but doesn't address my question. Thanks anyway!
  • Quoc Nguyen
    Quoc Nguyen over 9 years
    @mayabelle you can create IHttpActionResult concrete and wrapped those code like this:
  • Thomas.Benz
    Thomas.Benz about 8 years
    Short and simple solution. Having more codes means more bugs and time consuming maintenance.
  • Deza
    Deza almost 8 years
    When im trying this, the returned value of code (where code is a string) in return Content(HttpStatusCode.OK, code) is encapsulated in " which is unexpected, is there any reason for this? eg the value which is returned is "\"value\"" I'm using mvc5
  • user1620220
    user1620220 over 7 years
    Because not all errors are the result of bad requests, so a 400 response would be inappropriate. OP specifically gave a 500 response as an example.
  • Chemist
    Chemist over 7 years
    This worked for me but I used Request.CreateResponse so that the error shows as a string instead of under Message key.
  • benraay
    benraay about 7 years
    Yes it's only possible with BadRequest the other types don't take a message argument
  • Etherman
    Etherman almost 7 years
    If you need to do this from outside the ApiController class then you can use: return new NegotiatedContentResult<T>(code, new T(...), controller)
  • Etherman
    Etherman almost 7 years
    Shamil Yakupov's answer is the best answer but only from inside the ApiController class - it needs to be rewritten as something like "return new NegotiatedContentResult<T>(code, new T(...), controller)" to be used from outside the controller class. In that case a solution such as this one above may be more readable.
  • Sheena Agrawal
    Sheena Agrawal over 6 years
    I am getting an error, the snippet is failing. It says 'request' is null. I am trying to use Request.CreateResponse @user1620220
  • user1620220
    user1620220 over 6 years
    @SheenaAgrawal This code can only be executed in the context of an HTTP request. If ApiController.Request is null it means you are not in the right context, or something is broken in your WebAPI architecture.
  • userSteve
    userSteve about 6 years
    Yes but its a pain to get that message text back
  • LastTribunal
    LastTribunal almost 6 years
    Content<T> is very useful
  • Toolkit
    Toolkit almost 6 years
    can i return it from a class library? What do I need to reference?