我一直在使用WebApi开发并转移到WebApi2,其中Microsoft引入了一个新的IHttpActionResult
接口,似乎建议用于返回HttpResponseMessage
。我对这个新接口的优点感到困惑。它似乎主要只是提供一种轻微更简单的方法来创建HttpResponseMessage
。
我认为这是“为抽象而抽象”的论点。我错过了什么吗?除了可能保存一行代码之外,使用这个新接口可以获得什么样的真实优势?
旧方式(WebApi):
public HttpResponseMessage Delete(int id)
{
var status = _Repository.DeleteCustomer(id);
if (status)
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
新方法(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();
}
}
答案 0 :(得分:281)
您可能决定不使用IHttpActionResult
,因为您现有的代码会构建一个不适合其中一个预设回复的HttpResponseMessage
。但是,您可以使用HttpResponseMessage
的预设回复将IHttpActionResult
调整为ResponseMessage
。我花了一段时间来弄明白这一点,所以我想发布它表明你不必选择其中一个:
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;
}
注意,ResponseMessage
是控制器应该继承的基类ApiController
的方法。
答案 1 :(得分:83)
您仍然可以使用HttpResponseMessage
。这种能力不会消失。我感觉和你一样,并且与团队广泛争论,不需要额外的抽象。有一些争论试图证明它的存在,但没有任何让我相信它是值得的。
也就是说,直到我看到来自 Brad Wilson 的this样本。如果您以可链接的方式构建IHttpActionResult
类,则可以创建“操作级”响应管道以生成HttpResponseMessage
。在幕后,这是ActionFilters
的实现方式,但是,在阅读动作方法时,ActionFilters
的排序并不明显,这是我不喜欢动作过滤器的一个原因。
但是,通过创建可在操作方法中明确链接的IHttpActionResult
,您可以撰写各种不同的行为来生成响应。
答案 2 :(得分:55)
IHttpActionResult
提到的HttpResponseMessage
优于IHttpActionResult
的好处有几个好处:
- 简化控制器的单元测试。
- 将用于创建HTTP响应的通用逻辑移动到单独的类中。
- 通过隐藏构建响应的低级细节,使控制器操作的意图更加清晰。
但是,使用Ok
值得一提的其他一些优点是:
NotFound
Exception
Unauthorized
BadRequest
Conflict
Redirect
InvalidModelState
ExecuteAsync
(Microsoft ASP.Net Documentation)ResponseMessageResult ResponseMessage(HttpResponseMessage response)
方法即可轻松创建自己的ActionResult 。答案 3 :(得分:30)
// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage);
答案 4 :(得分:17)
这只是我个人的意见,来自网络API团队的人可能会更好地表达它,但这是我的2c。
首先,我认为这不是一个问题。你可以根据你在动作方法中想要做的事情来使用它们,但是为了理解IHttpActionResult
的真正力量,你可能需要走出那些方便的ApiController
辅助方法,如Ok
,NotFound
等
基本上,我认为实现IHttpActionResult
的班级是HttpResponseMessage
的工厂。有了这个心态,它现在变成了一个需要返回的对象和一个生成它的工厂。在一般编程意义上,您可以在某些情况下自己创建对象,在某些情况下,您需要工厂来执行此操作。同样在这里。
如果要返回需要通过复杂逻辑构建的响应,例如许多响应头等,您可以将所有这些逻辑抽象为实现IHttpActionResult
的操作结果类,并在多个中使用它返回响应的动作方法。
使用IHttpActionResult
作为返回类型的另一个好处是,它使ASP.NET Web API操作方法与MVC类似。您可以返回任何操作结果,而不会被媒体格式化程序捕获。
当然,正如Darrel所指出的,您可以在API管道中链接动作结果并创建类似于消息处理程序的强大微管道。根据行动方法的复杂程度,您需要这样做。
长话短说 - 不是IHttpActionResult
与HttpResponseMessage
。基本上,它是您想要创建响应的方式。自己动手或通过工厂自己动手。
答案 5 :(得分:5)
Web API基本上返回4种类型的对象:void
,HttpResponseMessage
,IHttpActionResult
和其他强类型。 Web API的第一个版本返回HttpResponseMessage
,这是非常简单的HTTP响应消息。
IHttpActionResult
是由WebAPI 2引入的,它是HttpResponseMessage
的一种包装。它包含ExecuteAsync()
方法来创建HttpResponseMessage
。它简化了控制器的单元测试。
其他返回类型是一种强类型类,由Web API使用媒体格式化程序序列化到响应主体中。缺点是您不能直接返回错误代码,例如404.您所能做的就是抛出HttpResponseException
错误。
答案 6 :(得分:3)
我宁愿为IHttpActionResult实现TaskExecuteAsync接口函数。类似的东西:
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);
}
,其中_request是HttpRequest,_respContent是有效负载。
答案 7 :(得分:1)
使用IHttpActionResult
优于HttpResponseMessage
:
IHttpActionResult
,我们只专注于要发送的数据而不是状态代码。所以这里的代码将更清晰,更易于维护。async
和await
。