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:
- IHttpActionResult is replaced with IActionResult in ASP.NET Core 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 GMThello
I hope this helps. Good luck.
Related Topics
An ASP.NET Setting Has Been Detected That Does Not Apply in Integrated Managed Pipeline Mode
Entity Framework - Code First - Can't Store List<String>
Searching for File in Directories Recursively
Dictionary Returning a Default Value If the Key Does Not Exist
Serialize Dictionary as Array (Of Key Value Pairs)
Which Cryptographic Hash Function Should I Choose
Options for Embedding Chromium Instead of Ie Webbrowser Control with Wpf/C#
How to Resolve Ioptions Instance Inside Configureservices
.Net: Determine the Type of "This" Class in Its Static Method
Why Use Simple Properties Instead of Fields in C#
How to Set Up Automapper in ASP.NET Core
The Difference Between Try/Catch/Throw and Try/Catch(E)/Throw E