[英]ASP.Net WebAPI: How to use IHttpActionResult instead of HttpResponseMessage
[英]Why should I use IHttpActionResult instead of HttpResponseMessage?
我一直在使用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();
}
}
您可能决定不使用IHttpActionResult
因为您的现有代码构建了一个不适合其中一个IHttpActionResult
响应的HttpResponseMessage
。 但是,您可以使用ResponseMessage
IHttpActionResult
响应将HttpResponseMessage
调整为IHttpActionResult
。 我花了一段时间来弄明白这一点,所以我想发布它表明你不必选择其中一个:
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
的方法。
您仍然可以使用HttpResponseMessage
。 这种能力不会消失。 我感觉和你一样,并且与团队广泛争论,不需要额外的抽象。 有一些争论试图证明它的存在,但没有任何让我相信这是值得的。
也就是说,直到我看到Brad Wilson的 这个样本。 如果以可链接的方式构造IHttpActionResult
类,则可以创建用于生成HttpResponseMessage
的“操作级”响应管道。 在ActionFilters
,这就是ActionFilters
的实现方式,然而,在阅读动作方法时,这些ActionFilters
的排序并不明显,这是我不喜欢动作过滤器的一个原因。
但是,通过创建可以在操作方法中显式链接的IHttpActionResult
,您可以IHttpActionResult
各种不同的行为来生成响应。
以下是Microsoft ASP.Net文档中提到的HttpResponseMessage
的IHttpActionResult
几个好处:
- 简化控制器的单元测试。
- 将用于创建HTTP响应的通用逻辑移动到单独的类中。
- 通过隐藏构造响应的低级细节,使控制器操作的意图更加清晰。
但是,使用IHttpActionResult
值得一提的其他一些优点:
Ok
NotFound
Exception
Unauthorized
BadRequest
Conflict
Redirect
InvalidModelState
( 链接到完整列表 ) ExecuteAsync
方法即可轻松创建自己的ActionResult 。 ResponseMessageResult ResponseMessage(HttpResponseMessage response)
将HttpResponseMessage转换为IHttpActionResult 。 // this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage);
这只是我个人的观点,来自Web API团队的人可能会更好地表达它,但这是我的2c。
首先,我认为这不是一个问题。 你可以根据你在动作方法中想要做的事情来使用它们,但为了理解IHttpActionResult
的真正威力,你可能需要走出ApiController
方便帮助方法,如Ok
, NotFound
等。
基本上,我认为一个实现IHttpActionResult
的类是HttpResponseMessage
的工厂。 有了这个心态,它现在变成了一个需要返回的对象和一个生成它的工厂。 在一般编程意义上,您可以在某些情况下自己创建对象,在某些情况下,您需要工厂来执行此操作。 同样在这里。
如果要返回需要通过复杂逻辑构建的响应,例如大量响应头等,您可以将所有这些逻辑抽象为实现IHttpActionResult
的操作结果类,并在多个操作方法中使用它来返回响应。
使用IHttpActionResult
作为返回类型的另一个好处是它使ASP.NET Web API操作方法类似于MVC。 您可以返回任何操作结果,而不会被媒体格式化程序捕获。
当然,正如Darrel所指出的,您可以在API管道中链接动作结果并创建类似于消息处理程序的强大微管道。 这将取决于您的操作方法的复杂性。
长话短说 - 不是IHttpActionResult
与HttpResponseMessage
。 基本上,它是您想要创建响应的方式。 自己动手或通过工厂自己动手。
Web API基本上返回4种类型的对象: void
, HttpResponseMessage
, IHttpActionResult
和其他强类型。 Web API的第一个版本返回HttpResponseMessage
,这是非常直接的HTTP响应消息。
IHttpActionResult
是由WebAPI 2引入的,它是HttpResponseMessage
的一种包装。 它包含用于创建HttpResponseMessage
的ExecuteAsync()
方法。 它简化了控制器的单元测试。
其他返回类型是Web API使用媒体格式化程序序列化到响应主体中的强类型类。 缺点是您无法直接返回错误代码,例如404.您所能做的就是抛出HttpResponseException
错误。
我宁愿为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是有效负载。
使用IHttpActionResult
不是HttpResponseMessage
有以下好处:
IHttpActionResult
我们只专注于要发送的数据而不是状态代码。 所以这里的代码将更清晰,更易于维护。 async
和await
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.