Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return Custom HTTP Status Code from WebAPI 2 endpoint

I'm working on a service in WebAPI 2, and the endpoint currently returns an IHttpActionResult. I'd like to return a status code 422, but since it's not in the HttpStatusCode enumeration, I'm at a loss as to how it would be sent, since all of the constructors require a parameter of HttpStatusCode

As it stands now, I'm returning BadResult(message), but returning a 422 + message would be more descriptive and useful for my clients. Any ideas?

like image 908
Garrison Neely Avatar asked Apr 30 '14 22:04

Garrison Neely


People also ask

How do I return IHttpActionResult in Web API?

If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message. More often, you use the IHttpActionResult implementations defined in the System. Web.

How do I return HTTP status?

Send Status Code using @ResponseStatus The reason is useful when the server returns unsuccessful statuses. The @ResponseStatus annotation can be used on any method that returns back a response to the client. Thus we can use it on controllers or on exception handler methods.

How do I return a status code in Web API .NET core?

HTTP Status Code 204 is used to return NoContent status i.e., when request is completed and there is no requirement to redirect. Such HTTP Response it is returned using NoContent function. HTTP Status Code 400 is used to return BadRequest status i.e., when request has error from client side and it cannot be processed.


5 Answers

According to C# specification:

The set of values that an enum type can take on is not limited by its enum members. In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type

Therefore you can cast status code 422 to HttpStatusCode.

Example controller:

using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace CompanyName.Controllers.Api
{
    [RoutePrefix("services/noop")]
    [AllowAnonymous]
    public class NoOpController : ApiController
    {
        [Route]
        [HttpGet]
        public IHttpActionResult GetNoop()
        {
            return new System.Web.Http.Results.ResponseMessageResult(
                Request.CreateErrorResponse(
                    (HttpStatusCode)422,
                    new HttpError("Something goes wrong")
                )
            );
        }
    }
}
like image 152
lilo.jacob Avatar answered Oct 19 '22 14:10

lilo.jacob


 return Content((HttpStatusCode) 422, whatEver);

credit is for: Return content with IHttpActionResult for non-OK response

and your code must be <= 999

and please ignore codes between 100 to 200.

like image 42
peyman Avatar answered Oct 19 '22 14:10

peyman


I use this way simple and elegant.

public ActionResult Validate(User user)
{
     return new HttpStatusCodeResult((HttpStatusCode)500, 
               "My custom internal server error.");
}

Then angular controller.

function errorCallBack(response) {            
$scope.response = {
   code: response.status,
   text: response.statusText
}});    

Hope it helps you.

like image 3
Ricardo G Saraiva Avatar answered Oct 19 '22 15:10

Ricardo G Saraiva


Another simplified example:

public class MyController : ApiController
{
    public IHttpActionResult Get()
    {
        HttpStatusCode codeNotDefined = (HttpStatusCode)422;
        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);
like image 2
themefield Avatar answered Oct 19 '22 14:10

themefield


For this you may need to use an Action Filter Attribute. Nothing fancy. Just create a class and inherit it from ActionFilterAttribute class in c#. Then override a method named OnActionExecuting to implement this. Then just use this filter on the head of any controller. Following is a demo.

On the condition when you need to produce custom status code based message in ActionFilterAttribute you can write in following way:

        if (necessity_to_send_custom_code)
        {
            actionContext.Response = actionContext.Request.CreateResponse((HttpStatusCode)855, "This is custom error message for you");
        }

Hope this helps.

like image 1
Sajeeb Chandan Avatar answered Oct 19 '22 15:10

Sajeeb Chandan