我一直在用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();
}
}
您可能决定不使用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的一个方法。
下面是微软ASP中提到的IHttpActionResult优于HttpResponseMessage的几个优点。网络文档:
简化控制器的单元测试。
将用于创建HTTP响应的通用逻辑移动到单独的类中。
通过隐藏构造响应的底层细节,使控制器动作的意图更加清晰。
但是这里有一些使用IHttpActionResult的其他优点值得一提:
Respecting single responsibility principle: cause action methods to have the responsibility of serving the HTTP requests and does not involve them in creating the HTTP response messages.
Useful implementations already defined in the System.Web.Http.Results namely: Ok NotFound Exception Unauthorized BadRequest Conflict Redirect InvalidModelState (link to full list)
Uses Async and Await by default.
Easy to create own ActionResult just by implementing ExecuteAsync method.
you can use ResponseMessageResult ResponseMessage(HttpResponseMessage response) to convert HttpResponseMessage to IHttpActionResult.