IHttpActionResult
接口,该接口似乎建议用于返回HttpResponseMessage
的接口。我对这个新界面的优势感到困惑。它似乎主要只是提供一种稍微简单一些的方法来创建HttpResponseMessage
。 我认为这是“抽象的抽象”。我想念什么吗?除了可能节省一行代码之外,使用此新接口还能为我带来现实的好处吗? />新方法(WebApi2):
public HttpResponseMessage Delete(int id)
{
var status = _Repository.DeleteCustomer(id);
if (status)
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
#1 楼
您可能决定不使用IHttpActionResult
,因为您现有的代码会生成一个HttpResponseMessage
,它不符合罐装响应之一。但是,您可以使用HttpResponseMessage
的固定响应将IHttpActionResult
调整为ResponseMessage
。我花了一些时间才弄清楚这一点,因此我想发布它,以表明您不必选择其中一个: ResponseMessage
是控制器应从其继承的基类ApiController
的方法。评论
花了我一段时间才发现ResponseMessage现在是ResponseMessageResult。也许它最近已重命名?附言您还错过了答案中的新关键字,非常感谢您的建议:)
–伊利亚·切尔诺莫迪克(Ilya Chernomordik)
2015年2月6日15:14
@IlyaChernomordik ResponseMessage和ResponseMessageResult是两个不同的事物。 ResponseMessage()是控制器应从其继承的ApiController的方法,因此仅是方法调用。因此,那里不需要新的关键字。您可能没有从ApiController继承,或者您处于静态方法内。 ResponseMessageResult是ResponseMessage()的返回类型。
– AaronLS
2015年2月6日,19:10
@IlyaChernomordik我可以写出response = base.ResponseMessage(responseMsg),以使其更清楚地表明它是基类ApiController的方法
– AaronLS
15年2月6日在19:12
谢谢,我确实有一个服务没有从ApiController继承,这就是为什么要花一些时间才能找到它的原因。
–伊利亚·切尔诺莫迪克(Ilya Chernomordik)
2015年2月9日在9:24
@pootzko您说得对,我提到了一个事实,即OP似乎暗示他们认为这两种方法是互斥的,将它们称为“旧方法”与“新方法”,而实际上并非如此。我认为Darrel的答案很好地解释了返回IHttpActionResult的一些好处,并且我的答案演示了如何将旧的HttpResponseMessage转换为IHttpActionResult,从而可以兼得两者。
– AaronLS
15年5月26日在0:09
#2 楼
您仍然可以使用HttpResponseMessage
。这种能力不会消失。我的感觉和您一样,并与团队进行了广泛的辩论,认为不需要其他抽象。有一些争论试图证明它的存在,但是没有什么使我确信它是值得的。,直到我看到布拉德·威尔逊的这个样本。如果以可链接的方式构造
IHttpActionResult
类,则可以创建“操作级”响应管道以生成HttpResponseMessage
的功能。在幕后,这是ActionFilters
的实现方式,但是,在阅读action方法时,ActionFilters
的顺序并不明显,这是我不喜欢action filter的原因之一。创建一个可以在您的操作方法中显式链接的IHttpActionResult
,您可以组合各种不同的行为来生成您的响应。#3 楼
这是IHttpActionResult
优于Microsoft ASP.Net文档中提到的HttpResponseMessage
的几个优点:简化了控制器的单元测试。将创建HTTP响应的通用逻辑移入单独的类。
通过隐藏构造响应的底层细节,使控制器操作的意图更加清晰。
但是这里还有其他一些优点
IHttpActionResult
的使用值得一提:指定单一责任原则:导致操作方法负责服务HTTP请求,并且不参与创建HTTP响应消息。
System.Web.Http。中已经定义的有用实现,结果是:
Ok
NotFound
Exception
Unauthorized
BadRequest
Conflict
Redirect
InvalidModelState
(链接到完整列表)默认情况下使用Async和Await。 br />
只需实现
ExecuteAsync
即可轻松创建自己的ActionResult可以。可以使用
ResponseMessageResult ResponseMessage(HttpResponseMessage response)
将HttpResponseMessage转换为IHttpActionResult。#4 楼
// this will return HttpResponseMessage as IHttpActionResult
return ResponseMessage(httpResponseMessage);
#5 楼
这只是我的个人观点,Web API团队的人们可能可以更好地表达它,但这是我的2c。首先,我认为这不是一个相互矛盾的问题。您可以根据要在操作方法中执行的操作来同时使用它们,但是为了了解IHttpActionResult
的真正功能,您可能需要跳出ApiController
的那些便捷助手方法,例如Ok
,NotFound
等。基本上,我认为是将IHttpActionResult
实现为HttpResponseMessage
的工厂的类。有了这种思想,现在它成为需要返回的对象并由工厂生产。在一般的编程意义上,您可以在某些情况下自己创建对象,并且在某些情况下,您需要工厂来执行此操作。在这里也是一样。如果要返回需要通过复杂的逻辑构造的响应,例如说很多响应头,等等,则可以将所有这些逻辑抽象为实现
IHttpActionResult
和在多种操作方法中使用它可以返回响应。使用
IHttpActionResult
作为返回类型的另一个优点是,它使ASP.NET Web API操作方法类似于MVC。您可以返回任何操作结果,而不会陷入媒体格式化程序中。 。取决于您的操作方法的复杂性。长话短说-它不是
IHttpActionResult
与HttpResponseMessage
。基本上,这就是您要如何创建响应。自己或通过工厂进行。评论
我在工厂调整中遇到的问题是,我可以轻松地创建返回HttpResponseMessage的静态方法(如ResponseFactory.CreateOkResponse()),并且在创建响应时不必处理异步内容。一位团队成员确实提到了以下事实:如果您需要执行I / O来生成标头值,那么异步可能会很有用。虽然不确定发生的频率。
– Darrel Miller
14年2月13日在17:32
我认为这与说为什么我们需要工厂方法模式相同。为什么不只是使用静态方法来创建对象。当然,这是可行的-每个对象创建都不具有适当的工厂模式。但是恕我直言,这取决于您要如何对类进行建模。您是否想要逻辑来创建不同类型的响应,这些响应都以多种静态方法的形式塞入一个类,或者具有基于接口的不同类。同样,没有好与坏。一切都取决于。无论如何,我的观点是,这不是一个相互重叠的过程,我个人更喜欢工厂的东西:)
–巴德里
14年2月13日在17:53
#6 楼
Web API基本上返回4种类型的对象:void
,HttpResponseMessage
,IHttpActionResult
和其他强类型。 Web API的第一个版本返回HttpResponseMessage
,这是非常简单的HTTP响应消息。IHttpActionResult
由WebAPI 2引入,它是HttpResponseMessage
的一种包装。它包含用于创建ExecuteAsync()
的HttpResponseMessage
方法。它简化了控制器的单元测试。 其他返回类型是由Web API使用媒体格式化程序序列化到响应正文中的强类型类。缺点是您无法直接返回错误代码(例如404)。您所能做的就是抛出
HttpResponseException
错误。#7 楼
我宁愿为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是有效负载。
#8 楼
与使用IHttpActionResult
相比,使用HttpResponseMessage
有以下好处:通过使用IHttpActionResult
,我们只专注于要发送的数据,而不关注状态码。因此,这里的代码将更加整洁,并且易于维护。实现的控制器方法的单元测试将更加容易。
默认情况下使用
async
和await
。
评论
我刚刚发现了一些有趣的东西。我不确定这些结果是否可以被其他人验证。但是通过执行一些调用,性能有了很大提高:*通过使用HttpResponseMessage的示例,我在9545 ms内获得了响应。 *使用IHttpActionResult,我在294毫秒内得到了相同的响应。@chrislesage 9545毫秒将近10秒。即使是294ms也有点慢。如果您花费的时间超过100毫秒,那么那里还有其他工作。这个故事比见识到的还要重要。