我为什么要使用IHttpActionResult而不是HttpResponseMessage?

Jas*_*ell 312 c# httpresponse asp.net-web-api

我一直在使用WebApi进行开发,并已转移到WebApi2,其中Microsoft引入了一个IHttpActionResult似乎建议用于返回a 的新接口HttpResponseMessage.我对这个新接口的优点感到困惑.这似乎主要是公正提供SLIGHTLY更简单的方法来创建一个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);
    }
}
Run Code Online (Sandbox Code Playgroud)

新方式(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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Aar*_*nLS 293

您可能决定不使用,IHttpActionResult因为您的现有代码构建的HttpResponseMessage内容不适合其中一个预设响应.但是,您可以适应HttpResponseMessageIHttpActionResult使用的罐头回应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;
}
Run Code Online (Sandbox Code Playgroud)

注意,ResponseMessageApiController控制器应该继承的基类的方法.

  • @IlyaChernomordik`ResponseMessage`和`ResponseMessageResult`是两回事.`ResponseMessage()`是你的控制器应该继承的`ApiController`的*方法*,因此它只是一个方法调用.所以那里不需要`new`关键字.您可能不是继承自`ApiController`或者您是静态方法.`ResponseMessageResult`是`ResponseMessage()`的返回类型. (10认同)
  • @pootzko你说得对,我说OP似乎意味着他们认为这两种方法是相互排斥的,将它描述为"旧方式"与"新方式",而事实上它们并非如此.我认为Darrel的答案很好地解释了返回IHttpActionResult的一些好处,我的答案演示了如何将旧的HttpResponseMessage转换为IHttpActionResult,以便您可以充分利用这两个世界. (3认同)
  • 我花了一段时间才发现 ResponseMessage 现在是 ResponseMessageResult。也许它最近改名了?PS您还错过了答案中的新关键字,非常感谢您的建议:) (2认同)
  • @IlyaChernomordik我本可以编写`response = base.ResponseMessage(responseMsg)`以使它更清楚它是基类ApiController的方法 (2认同)

Dar*_*ler 83

你仍然可以使用HttpResponseMessage.这种能力不会消失.我感觉和你一样,并且与团队广泛争论,不需要额外的抽象.有一些争论试图证明它的存在,但没有任何让我相信这是值得的.

也就是说,直到我看到Brad Wilson的这个样本.如果以可链接的方式构造类,则可以创建用于生成的"动作级"响应管道.在封面下,这是如何实现的,然而,在阅读动作方法时,这些的顺序并不明显,这是我不喜欢动作过滤器的一个原因.IHttpActionResultHttpResponseMessageActionFiltersActionFilters

但是,通过创建IHttpActionResult可以在操作方法中明确链接的,您可以组合各种不同的行为来生成响应.


Beh*_*yar 61

这里有几个好处IHttpActionResultHttpResponseMessage提到微软ASP.Net文档:

  • 简化控制器的单元测试.
  • 将用于创建HTTP响应的通用逻辑移动到单独的类中.
  • 通过隐藏构造响应的低级细节,使控制器操作的意图更加清晰.

但是这里有一些IHttpActionResult值得一提的其他优点:

  • 尊重单一责任原则:使操作方法负责提供HTTP请求,而不涉及创建HTTP响应消息.
  • 有用的实现中即System.Web.Http.Results已经定义:Ok NotFound Exception Unauthorized BadRequest Conflict Redirect InvalidModelState(链接到完整名单)
  • 默认情况下使用Async和Await.
  • 只需通过实现ExecuteAsync方法即可轻松创建自己的ActionResult.
  • 您可以使用ResponseMessageResult ResponseMessage(HttpResponseMessage response)HttpResponseMessage转换为IHttpActionResult.


Ada*_*Tal 32

// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage); 
Run Code Online (Sandbox Code Playgroud)


Bad*_*dri 17

这只是我个人的观点,来自Web API团队的人可能会更好地表达它,但这是我的2c.

首先,我认为这不是一个问题.您可以使用这两个取决于你想要在你的操作方法做什么,但为了了解真正的力量IHttpActionResult,你可能需要加强的那些方便的helper方法之外ApiController,例如Ok,NotFound等等.

基本上,我认为一个实现IHttpActionResult作为工厂的类HttpResponseMessage.有了这个心态,它现在变成了一个需要返回的对象和一个生成它的工厂.在一般编程意义上,您可以在某些情况下自己创建对象,在某些情况下,您需要工厂来执行此操作.同样在这里.

如果要返回需要通过复杂逻辑构建的响应,例如许多响应头等,您可以将所有这些逻辑抽象为一个动作结果类IHttpActionResult,在多个动作方法中实现并使用它来返回响应.

使用IHttpActionResult返回类型的另一个好处是它使ASP.NET Web API操作方法与MVC类似.您可以返回任何操作结果,而不会被媒体格式化程序捕获.

当然,正如Darrel所指出的,您可以在API管道中链接动作结果并创建类似于消息处理程序的强大微管道.这将取决于您的操作方法的复杂性.

长话短说 - 不是IHttpActionResult对抗HttpResponseMessage.基本上,它是您想要创建响应的方式.自己动手或通过工厂自己动手.


Pet*_*ang 5

在Web API基本上回到4类型的对象:void,HttpResponseMessage,IHttpActionResult,等强类型.Web API的第一个版本返回的HttpResponseMessage是非常简单的HTTP响应消息.

IHttpActionResult是由WebAPI 2引入的,它是一种包装HttpResponseMessage.它包含ExecuteAsync()创建的方法HttpResponseMessage.它简化了控制器的单元测试.

其他返回类型是Web API使用媒体格式化程序序列化到响应主体中的强类型类.缺点是您不能直接返回错误代码,如404.您所能做的就是抛出HttpResponseException错误.