本文翻译自:Why should I use IHttpActionResult instead of HttpResponseMessage?
I have been developing with WebApi and have moved on to WebApi2 where Microsoft has introduced a new IHttpActionResult
Interface that seems to recommended to be used over returning a HttpResponseMessage
. 我一直在使用WebApi开发并转移到WebApi2,其中Microsoft引入了一个新的IHttpActionResult
接口,似乎建议用于返回HttpResponseMessage
。 I am confused on the advantages of this new Interface. 我对这个新接口的优点感到困惑。 It seems to mainly just provide a SLIGHTLY easier way to create a HttpResponseMessage
. 这似乎主要是公正提供了一个稍微容易的方法来创建一个HttpResponseMessage
。
I would make the argument that this is "abstraction for the sake of abstraction". 我认为这是“为抽象而抽象”的论点。 Am I missing something? 我错过了什么吗? What is the real world advantages I get from using this new Interface besides maybe saving a line of code? 除了节省一行代码之外,使用这个新接口可以获得什么样的真实优势?
Old way (WebApi): 旧方式 (WebApi):
public HttpResponseMessage Delete(int id)
{
var status = _Repository.DeleteCustomer(id);
if (status)
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
New Way (WebApi2): 新方式 (WebApi2):
public IHttpActionResult Delete(int id)
{
var status = _Repository.DeleteCustomer(id);
if (status)
{
//return new HttpResponseMessage(HttpStatusCode.OK);
return Ok();
}
else
{
//throw new HttpResponseException(HttpStatusCode.NotFound);
return NotFound();
}
}
#1楼
参考:https://stackoom.com/question/1TIPP/我为什么要使用IHttpActionResult而不是HttpResponseMessage
#2楼
You can still use HttpResponseMessage
. 您仍然可以使用HttpResponseMessage
。 That capability will not go away. 这种能力不会消失。 I felt the same way as you and argued extensively with the team that there was no need for an additional abstraction. 我感觉和你一样,并且与团队广泛争论,不需要额外的抽象。 There were a few arguments thrown around to try and justify its existence but nothing that convinced me that it was worthwhile. 有一些争论试图证明它的存在,但没有任何让我相信这是值得的。
That is, until I saw this sample from Brad Wilson . 也就是说,直到我看到Brad Wilson的 这个样本。 If you construct IHttpActionResult
classes in a way that can be chained, you gain the ability to create a "action-level" response pipeline for generating the HttpResponseMessage
. 如果以可链接的方式构造IHttpActionResult
类,则可以创建用于生成HttpResponseMessage
的“操作级”响应管道。 Under the covers, this is how ActionFilters
are implemented however, the ordering of those ActionFilters
is not obvious when reading the action method which is one reason I'm not a fan of action filters. 在ActionFilters
,这就是ActionFilters
的实现方式,然而,在阅读动作方法时,这些ActionFilters
的排序并不明显,这是我不喜欢动作过滤器的一个原因。
However, by creating an IHttpActionResult
that can be explicitly chained in your action method you can compose all kinds of different behaviour to generate your response. 但是,通过创建可以在操作方法中显式链接的IHttpActionResult
,您可以IHttpActionResult
各种不同的行为来生成响应。
#3楼
This is just my personal opinion and folks from web API team can probably articulate it better but here is my 2c. 这只是我个人的观点,来自Web API团队的人可能会更好地表达它,但这是我的2c。
First of all, I think it is not a question of one over another. 首先,我认为这不是一个问题。 You can use them both depending on what you want to do in your action method but in order to understand the real power of IHttpActionResult
, you will probably need to step outside those convenient helper methods of ApiController
such as Ok
, NotFound
, etc. 你可以根据你在动作方法中想要做的事情来使用它们,但为了理解IHttpActionResult
的真正威力,你可能需要走出ApiController
方便帮助方法,如Ok
, NotFound
等。
Basically, I think a class implementing IHttpActionResult
as a factory of HttpResponseMessage
. 基本上,我认为一个实现IHttpActionResult
的类是HttpResponseMessage
的工厂。 With that mind set, it now becomes an object that need to be returned and a factory that produces it. 有了这个心态,它现在变成了一个需要返回的对象和一个生成它的工厂。 In general programming sense, you can create the object yourself in certain cases and in certain cases, you need a factory to do that. 在一般编程意义上,您可以在某些情况下自己创建对象,在某些情况下,您需要工厂来执行此操作。 Same here. 同样在这里。
If you want to return a response which needs to be constructed through a complex logic, say lots of response headers, etc, you can abstract all those logic into an action result class implementing IHttpActionResult
and use it in multiple action methods to return response. 如果要返回需要通过复杂逻辑构建的响应,例如大量响应头等,您可以将所有这些逻辑抽象为实现IHttpActionResult
的操作结果类,并在多个操作方法中使用它来返回响应。
Another advantage of using IHttpActionResult
as return type is that it makes ASP.NET Web API action method similar to MVC. 使用IHttpActionResult
作为返回类型的另一个好处是它使ASP.NET Web API操作方法类似于MVC。 You can return any action result without getting caught in media formatters. 您可以返回任何操作结果,而不会被媒体格式化程序捕获。
Of course, as noted by Darrel, you can chain action results and create a powerful micro-pipeline similar to message handlers themselves in the API pipeline. 当然,正如Darrel所指出的,您可以在API管道中链接动作结果并创建类似于消息处理程序的强大微管道。 This you will need depending on the complexity of your action method. 这将取决于您的操作方法的复杂性。
Long story short - it is not IHttpActionResult
versus HttpResponseMessage
. 长话短说 - 不是IHttpActionResult
与HttpResponseMessage
。 Basically, it is how you want to create the response. 基本上,它是您想要创建响应的方式。 Do it yourself or through a factory. 自己动手或通过工厂自己动手。
#4楼
You might decide not to use IHttpActionResult
because your existing code builds a HttpResponseMessage
that doesn't fit one of the canned responses. 您可能决定不使用IHttpActionResult
因为您的现有代码构建了一个不适合其中一个IHttpActionResult
响应的HttpResponseMessage
。 You can however adapt HttpResponseMessage
to IHttpActionResult
using the canned response of ResponseMessage
. 但是,您可以使用ResponseMessage
IHttpActionResult
响应将HttpResponseMessage
调整为IHttpActionResult
。 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. 注意, ResponseMessage
是控制器应该继承的基类ApiController
的方法。
#5楼
// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage);
#6楼
I'd rather implement TaskExecuteAsync interface function for IHttpActionResult. 我宁愿为IHttpActionResult实现TaskExecuteAsync接口函数。 Something like: 就像是:
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);
switch ((Int32)_respContent.Code)
{
case 1:
case 6:
case 7:
response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);
break;
case 2:
case 3:
case 4:
response = _request.CreateResponse(HttpStatusCode.BadRequest, _respContent);
break;
}
return Task.FromResult(response);
}
, where _request is the HttpRequest and _respContent is the payload. ,其中_request是HttpRequest,_respContent是有效负载。