繁体   English   中英

我为什么要使用IHttpActionResult而不是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文档中提到的HttpResponseMessageIHttpActionResult几个好处:

  • 简化控制器的单元测试。
  • 将用于创建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
// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage); 

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

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

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

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

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

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

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

Web API基本上返回4种类型的对象: voidHttpResponseMessageIHttpActionResult和其他强类型。 Web API的第一个版本返回HttpResponseMessage ,这是非常直接的HTTP响应消息。

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

其他返回类型是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有以下好处:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM