HttpResponseMessage和HttpResponseException有什么区别?

我试图理解这两个,并写示例代码:

public HttpResponseMessage Get() { var response = ControllerContext.Request .CreateResponse(HttpStatusCode.BadRequest, "abc"); throw new HttpResponseException(response); } 

和:

  public HttpResponseMessage Get() { return ControllerContext.Request .CreateResponse(HttpStatusCode.BadRequest, "abc"); } 

从小提琴,我真的没有看到他们之间的任何区别,那么使用HttpResponseException的目的是什么?

两者的主要区别在于这一点。 这个例外是有用的立即停止处理和退出。 例如,假设我有以下代码

 public class CustomerController : ApiController { private ICustomerContext repo; public CustomerController(ICustomerContext repo) { this.repo = repo; } public Customer Get(int id) { var customer = repo.Customers.SingleOrDefault(c=>c.CustomerID == id); if (customer == null) { throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); } return customer; } } 

如果这个代码运行,我传递一个不存在的ID,它将立即停止处理,并返回一个404状态码。

如果相反,我返回HttpResponseMessage,请求将愉快地继续其余的处理,并返回一个404。主要的区别是结束请求或不。

正如Darrel所说,这种例外情况在某些情况下我希望继续处理(例如发现客户的时候),而在其他情况下则不会。

您可能想要使用类似HttpResponseMessage的地方是在Http POST中返回状态代码201并设置位置标题。 在这种情况下,我确实希望继续处理。 这将与这个代码。*

 public class CustomerController : ApiController { private ICustomerContext repo; public CustomerController(ICustomerContext repo) { this.repo = repo; } public HttpResponseMessage Post(Customer customer) { repo.Add(customer); repo.SaveChanges(); var response = Request.CreateResponse(HttpStatusCode.Created, customer); response.Headers.Location = new Uri(Request.RequestUri, string.format("customer/{0}", customer.id)); return response; } } 

*注意:如果您正在使用testing位,您将创build一个新的HttpResponseMessage。 我正在使用后面的位,但是要求您使用CreateResponse扩展方法closures请求。

上面,我创build一个响应,将状态码设置为201,传入客户,然后设置位置标题。

然后返回响应,请求继续处理。

希望这可以帮助

当您的Controller Action签名看起来像HttpResponseException是有用的

  Foo Get(int id) 

在这种情况下,您不能轻松返回400状态码。

请注意, HttpResponseMessage<T>将在下一个Web API版本中消失。

假设你想unit testing响应,总是返回一个HttpResponseMessage是否有意义? 我不特别喜欢从ApiController返回直接types的想法,因为它不遵循典型的开发模式。

在获取Customer的非Web API类中,您可能会返回null,您的调用代码将检查null响应:

 public Customer GetCustomer(int id) { return db.Customers.Find(id); } 

但是在Web API中,您不会返回null,即使在抛出HttpResponseException之后创build了某些内容,您也必须返回一些内容。 在这种情况下,为了简化testing,为什么不只是总是返回一个HttpResponseMessage,并让你的签名?

 public HttpResponseMessage GetCustomer(int id) { var customer = db.Customers.Find(id); if (customer == null) { return Request.CreateResponse(HttpStatusCode.NotFound); } return Request.CreateResponse(HttpStatusCode.OK, customer); } 

HttpResponseExceptionException派生并embedded了HttpResponseMessage 。 由于它来自Exception所以在trycatch场景中可能很有用。

HttpResponseException返回的默认状态代码是HttpStatusCode.InternalServerError

正如原来的问题所述,返回的答案没有实质性的区别。

HttpResponseException的真正目的是允许子方法创build并抛出自己的HttpResponseMessages,这些HttpResponseMessages返回到调用堆栈并返回给客户端。

 public class CustomerController : ApiController { private ICustomerContext repo; public CustomerController(ICustomerContext repo) { this.repo = repo; } public HttpResponseMessage Get(int id) { Customer customer = getCustomer(id); return Request.CreateResponse(customer); } private Customer getCustomer(int id){ .....do some work .....we have a problem so throw exception throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, "Id out of range"); return repo.Customers.SingleOrDefault(c=>c.CustomerID == id) } 

原谅任何错误,即时编写的代码。 引发的HttpResponseException通过动作调用堆栈起泡,不会被正常的Exception处理程序捕获,并像Action方法本身一样返回其HttpResponseMessage。