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

时间:2014-02-13 15:34:08

标签: c# asp.net-web-api httpresponse

我一直在使用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();
    }
}

8 个答案:

答案 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值得一提的其他一些优点是:

  • 尊重单一责任原则:使行动方法有责任为HTTP请求提供服务,并且不会让他们参与创建HTTP响应消息。
  • 已在System.Web.Http.Results中定义的有用实现NotFound Exception Unauthorized BadRequest Conflict Redirect InvalidModelState ExecuteAsyncMicrosoft ASP.Net Documentation
  • 默认使用异步和等待
  • 只需实施ResponseMessageResult ResponseMessage(HttpResponseMessage response)方法即可轻松创建自己的ActionResult
  • 您可以使用{{1}} 将HttpResponseMessage转换为IHttpActionResult

答案 3 :(得分:30)

// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage); 

答案 4 :(得分:17)

这只是我个人的意见,来自网络API团队的人可能会更好地表达它,但这是我的2c。

首先,我认为这不是一个问题。你可以根据你在动作方法中想要做的事情来使用它们,但是为了理解IHttpActionResult的真正力量,你可能需要走出那些方便的ApiController辅助方法,如OkNotFound

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

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

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

当然,正如Darrel所指出的,您可以在API管道中链接动作结果并创建类似于消息处理程序的强大微管道。根据行动方法的复杂程度,您需要这样做。

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

答案 5 :(得分:5)

Web API基本上返回4种类型的对象:voidHttpResponseMessageIHttpActionResult和其他强类型。 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

,我们有以下好处
  1. 通过使用IHttpActionResult,我们只专注于要发送的数据而不是状态代码。所以这里的代码将更清晰,更易于维护。
  2. 实施控制器方法的单元测试将更容易。
  3. 默认情况下使用asyncawait