我一直在用WebApi开发,已经转移到WebApi2,微软已经引入了一个新的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();
}
}
这只是我个人的观点,来自web API团队的人可能会更好地表达它,但这里是我的2c。
首先,我认为这不是一个人胜过另一个人的问题。你可以使用它们,这取决于你想在你的动作方法中做什么,但为了理解IHttpActionResult的真正力量,你可能需要走出ApiController的那些方便的帮助方法,如Ok, NotFound,等等。
基本上,我认为实现IHttpActionResult的类是HttpResponseMessage的工厂。有了这种心态,它现在就变成了一个需要返回的对象和一个生产它的工厂。在一般编程的意义上,您可以在某些情况下自己创建对象,在某些情况下,您需要一个工厂来做这件事。我也一样。
如果你想返回一个需要通过复杂逻辑构造的响应,比如许多响应头,等等,你可以将所有这些逻辑抽象到实现IHttpActionResult的操作结果类中,并在多个操作方法中使用它来返回响应。
使用IHttpActionResult作为返回类型的另一个优点是它使ASP。NET Web API动作方法类似MVC。您可以返回任何操作结果,而不会被媒体格式化程序捕获。
当然,正如Darrel所指出的,您可以将操作结果链接起来,并在API管道中创建一个类似于消息处理程序本身的强大微管道。这取决于您的操作方法的复杂性。
长话短说——它不是IHttpActionResult和HttpResponseMessage。基本上,这是你想要创建响应的方式。你可以自己做,也可以去工厂做。
这只是我个人的观点,来自web API团队的人可能会更好地表达它,但这里是我的2c。
首先,我认为这不是一个人胜过另一个人的问题。你可以使用它们,这取决于你想在你的动作方法中做什么,但为了理解IHttpActionResult的真正力量,你可能需要走出ApiController的那些方便的帮助方法,如Ok, NotFound,等等。
基本上,我认为实现IHttpActionResult的类是HttpResponseMessage的工厂。有了这种心态,它现在就变成了一个需要返回的对象和一个生产它的工厂。在一般编程的意义上,您可以在某些情况下自己创建对象,在某些情况下,您需要一个工厂来做这件事。我也一样。
如果你想返回一个需要通过复杂逻辑构造的响应,比如许多响应头,等等,你可以将所有这些逻辑抽象到实现IHttpActionResult的操作结果类中,并在多个操作方法中使用它来返回响应。
使用IHttpActionResult作为返回类型的另一个优点是它使ASP。NET Web API动作方法类似MVC。您可以返回任何操作结果,而不会被媒体格式化程序捕获。
当然,正如Darrel所指出的,您可以将操作结果链接起来,并在API管道中创建一个类似于消息处理程序本身的强大微管道。这取决于您的操作方法的复杂性。
长话短说——它不是IHttpActionResult和HttpResponseMessage。基本上,这是你想要创建响应的方式。你可以自己做,也可以去工厂做。
我宁愿为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,该HttpResponseMessage不适合其中一个封闭响应。但是,您可以使用ResponseMessage的罐装响应将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的一个方法。