Why Should I Use Ihttpactionresult Instead of Httpresponsemessage

Why should I use IHttpActionResult instead of HttpResponseMessage?

You might decide not to use IHttpActionResult because your existing code builds a HttpResponseMessage that doesn't fit one of the canned responses. You can however adapt HttpResponseMessage to IHttpActionResult using the canned response of ResponseMessage. It took me a while to figure this out, so I wanted to post it showing that you don't necesarily have to choose one or the other:

public IHttpActionResult SomeAction()
{
IHttpActionResult response;
//we want a 303 with the ability to set location
HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.RedirectMethod);
responseMsg.Headers.Location = new Uri("http://customLocation.blah");
response = ResponseMessage(responseMsg);
return response;
}

Note, ResponseMessage is a method of the base class ApiController that your controller should inherit from.

ASP.Net WebAPI: How to use IHttpActionResult instead of HttpResponseMessage

There are two ways to deal with this

First one is simple by changing the return type and passing the HttpResponseMessage to ResponseMessage which returns a IHttpActionResult derived class.

[HttpGet]
[Route("UserAppointments/{email}")]
public IHttpActionResult UserAppointments(string email = null) {
HttpResponseMessage retObject = null;
if (!string.IsNullOrEmpty(email)) {
UserAppointmentService _appservice = new UserAppointmentService();
IEnumerable<Entities.UserAppointments> app = _appservice.GetAppointmentsByEmail(email);

if (app.Count() <= 0) {
var message = string.Format("No appointment found for the user [{0}]", email);
HttpError err = new HttpError(message);
retObject = Request.CreateErrorResponse(System.Net.HttpStatusCode.NotFound, err);
retObject.ReasonPhrase = message;
} else {
retObject = Request.CreateResponse(System.Net.HttpStatusCode.OK, app);
}
} else {
var message = string.Format("No email provided");
HttpError err = new HttpError(message);
retObject = Request.CreateErrorResponse(System.Net.HttpStatusCode.NotFound, err);
retObject.ReasonPhrase = message;

}
return ResponseMessage(retObject);
}

The alternative is to refactor the method to follow the syntax suggestions from Asp.Net Web API 2 documentation.

[HttpGet]
[Route("UserAppointments/{email}")]
public IHttpActionResult UserAppointments(string email = null) {
if (!string.IsNullOrEmpty(email)) {
var _appservice = new UserAppointmentService();
IEnumerable<Entities.UserAppointments> app = _appservice.GetAppointmentsByEmail(email);
if (app.Count() <= 0) {
var message = string.Format("No appointment found for the user [{0}]", email);
return Content(HttpStatusCode.NotFound, message);
}
return Ok(app);
}
return BadRequest("No email provided");
}

Reference Action Results in Web API 2

Convert from HttpResponseMessage to IActionResult in .NET Core

You can return using hardset status codes like Ok(); or BadRequest();

Or return using a dynamic one using

StatusCode(<Your status code number>,<Optional return object>);

This is using Microsoft.AspNetCore.Mvc

Below is this.StatusCode spelled out a little more:

/* "this" comes from your class being a subclass of Microsoft.AspNetCore.Mvc.ControllerBase */
StatusCodeResult scr = this.StatusCode(200);
/* OR */
Object myObject = new Object();
ObjectResult ores = this.StatusCode(200, myObject);
return scr; /* or return ores;*/

Web API Best Approach for returning HttpResponseMessage

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.

IHttpActionResult vs IActionResult

IHttpActionResult is for ASP.NET Web Api, while IActionResult is for ASP.NET Core. There's no such thing as "Web Api" in ASP.NET Core. It's all just "Core". However, some people still refer to creating an ASP.NET Core API as a "Web Api", which adds to the confusion.

Easiest way to convert HttpResponseMessage to HttpActionResult outside of a controller

the MSDN page will help you: https://learn.microsoft.com/en-us/aspnet/web-api/overview/error-handling/web-api-global-error-handling

you need a global error handler. here is core code, you will find details in MSDN page.

class OopsExceptionHandler : ExceptionHandler
{
public override void HandleCore(ExceptionHandlerContext context)
{
context.Result = new TextPlainErrorResult
{
Request = context.ExceptionContext.Request,
Content = "Oops! Sorry! Something went wrong." +
"Please contact support@contoso.com so we can try to fix it."
};
}

private class TextPlainErrorResult : IHttpActionResult
{
public HttpRequestMessage Request { get; set; }

public string Content { get; set; }

public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage response =
new HttpResponseMessage(HttpStatusCode.InternalServerError);
response.Content = new StringContent(Content);
response.RequestMessage = Request;
return Task.FromResult(response);
}
}
}

BTW, you should mention MVC version:

  1. IHttpActionResult is replaced with IActionResult in ASP.NET Core 2:
  2. ExceptionHandlerContext is in System.Web.Http, no longer exist too.
    here is details: https://learn.microsoft.com/en-us/aspnet/core/migration/webapi?view=aspnetcore-2.1#migrate-models-and-controllers

Is there a difference in what's sent back between HttpResponseMessage and Task IHttpActionResult using WebAPI 2?

In Web API version 1, you could either return HTTP 200 by returning a value, or you would have to construct a HttpResponseMessage to return anything else.

In Web API 2, IHttpActionResult and the associated Ok(), BadRequest(), Created(), etc ApiController methods were added to simplify many situations where you simply want to respond with a different status code. Behind the scenes, Web API calls IHttpActionResult.ExecuteAsync() to convert it into an HttpResponseMessage.

For more details, see: Action Results in Web API 2

As for the ResponseType attribute, it's mainly there to specify the return type in actions that return IHttpActionResult and HttpResponseMessage so that Web API can generate the help documentation. Previously, this had to be done via config.SetActualResponseType().

More details: ResponseTypeAttribute

return type in webAPI call

Based on the Microsoft ASP.NET Documentation,

The IHttpActionResult interface was introducted in Web API 2. Essentially, it defines an HttpResponseMessage factory. Here are some advantages of using the IHttpActionResult interface:

  • Simplifies unit testing your controllers.
  • Moves common logic for creating HTTP responses into separate classes.
  • Makes the intent of the controller action clearer, by hiding the
    low-level details of constructing the response.

IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance.

public interface IHttpActionResult
{
Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
}

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.

Here is a simple implementaton of IHttpActionResult that creates a plain text response:

public class TextResult : IHttpActionResult
{
string _value;
HttpRequestMessage _request;

public TextResult(string value, HttpRequestMessage request)
{
_value = value;
_request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage()
{
Content = new StringContent(_value),
RequestMessage = _request
};
return Task.FromResult(response);
}
}

Another Sample in Controller:

public class ValuesController : ApiController
{
public IHttpActionResult Get()
{
return new TextResult("hello", Request);
}
}

And Its Respond:

HTTP/1.1 200 OK Content-Length: 5 Content-Type: text/plain;
charset=utf-8 Server: Microsoft-IIS/8.0 Date: Mon, 27 Jan 2014
08:53:35 GMT

hello

I hope this helps. Good luck.



Related Topics



Leave a reply



Submit