Web API Best Approach for returning HttpResponseMessage
Asked Answered
S

4

33

I have a Web API project and right my methods always returns HttpResponseMessage.

So, if it works or fails I return:

No errors:

return Request.CreateResponse(HttpStatusCode.OK,"File was processed.");

Any error or fail

return Request.CreateResponse(HttpStatusCode.NoContent, "The file has no content or rows to process.");

When I return an object then I use:

return Request.CreateResponse(HttpStatusCode.OK, user);

I would like to know how can I return to my HTML5 client a better encapsulated respose, so I can return more information about the transaction, etc.

I was thinking on creating a custom class that can encapsulate the HttpResponseMessage but also have more data.

Does anyone have implemented something similar?

Savina answered 11/4, 2014 at 14:56 Comment(2)
You should not use any Content in a HttpStatusCode.NoContent.Matsu
Generally if you return a HttpActionResult with HttpStatusCode.NoContent, it will - surprise - return no content, even if you are passing in a string like in your case above. Can be a surprising bug. Like user BigTone 's answer below. This makes sense too according to the specification httpstatuses.com/204 A 204 response is terminated by the first empty line after the header fields because it cannot contain a message body.Late
C
37

Although this is not directly answering the question, I wanted to provide some information I found usefull. http://weblogs.asp.net/dwahlin/archive/2013/11/11/new-features-in-asp-net-web-api-2-part-i.aspx

The HttpResponseMessage has been more or less replaced with IHttpActionResult. It is much cleaner an easier to use.

public IHttpActionResult Get()
{
     Object obj = new Object();
     if (obj == null)
         return NotFound();
     return Ok(obj);
 }

Then you can encapsulate to create custom ones. How to set custom headers when using IHttpActionResult?

I haven't found a need yet for implementing a custom result yet but when I do, I will be going this route.

Its probably very similar to do using the old one as well.

To expand further on this and provide a bit more info. You can also include messages with some of the requests. For instance.

return BadRequest("Custom Message Here");

You can't do this with many of the other ones but helps for common messages you want to send back.

Circumnavigate answered 11/4, 2014 at 15:12 Comment(2)
Thanks to you, I will never use the dreaded HttpResponseMessage againIndividualize
And if you're using MVC Core or whatever it's called today, the type you're looking for might be called IActionResultGoldschmidt
T
8

You can return an error response to provide more detail.

public HttpResponseMessage Get()
{
    HttpError myCustomError = new HttpError("The file has no content or rows to process.") { { "CustomErrorCode", 42 } };
     return Request.CreateErrorResponse(HttpStatusCode.BadRequest, myCustomError);
 }

Would return:

{ 
  "Message": "The file has no content or rows to process.", 
  "CustomErrorCode": 42 
}

More details here: http://blogs.msdn.com/b/youssefm/archive/2012/06/28/error-handling-in-asp-net-webapi.aspx

I also use http://en.wikipedia.org/wiki/List_of_HTTP_status_codes to help me determine what http status code to return.

Trilinear answered 11/4, 2014 at 17:31 Comment(0)
O
4

One important note: Don't put content in 204 responses! Not only is it against the HTTP specification, but .NET can actually behave in unexpected manners if you do.

I mistakenly used return Request.CreateResponse(HttpStatusCode.NoContent, null); and it led to a real headache; future requests from the same session would break due to having a "null" string value prepended to the response. I guess .NET doesn't always do a full clear of the response object for API calls from the same session.

Orometer answered 14/7, 2015 at 21:18 Comment(1)
Generally if you return a HttpActionResult with HttpStatusCode.NoContent, it will - surprise - return no content, even if you are passing in content like in OP's case above. Can be a surprising bug.Late
S
0

I'm learning so don't what I'm about to say may be silly (or not).

Why not create a class/model for your APIResponse? Something like:

 public class APIResponse
    {
        public HttpStatusCode StatusCode { get; set; }
        public bool IsSuccess { get; set; } = true;
        public List<string> Messages { get; set; }
        public object Object { get; set; }
    }

Then you have a standard response easier to read and you can always add more information if you need to.

Salute answered 2/2, 2023 at 13:54 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.