我试图理解这两个并编写示例代码:
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
的目的是什么?
答案 0 :(得分:66)
两者之间的主要区别在于此。该异常对于立即停止处理和退出很有用。例如,假设我有以下代码
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;
}
}
*注意:如果您使用的是beta位,则会创建一个新的HttpResponseMessage。我正在使用后面的位,但是要求您使用Request的CreateResponse扩展方法。
上面,我正在创建一个响应,它将状态代码设置为201,传入客户,然后设置位置标题。
然后返回响应并继续处理请求。
希望这有帮助
答案 1 :(得分:28)
当您的Controller Action签名看起来像
时,HttpResponseException非常有用 Foo Get(int id)
在这种情况下,您无法轻松返回状态代码,如400.
请注意,HttpResponseMessage<T>
将在下一版Web API中消失。
答案 2 :(得分:13)
假设您想要对响应进行单元测试,那么始终返回HttpResponseMessage是否有意义?我并不特别喜欢从ApiController返回直接类型的想法,因为它不遵循典型的开发模式。
在获取Customer的非Web API类中,您可能会返回null,并且您的调用代码会检查null响应:
public Customer GetCustomer(int id)
{
return db.Customers.Find(id);
}
但是在Web API中,你不会返回null,你必须返回一些内容,即使在抛出HttpResponseException之后创建了某些东西。在这种情况下,为了简化测试,为什么不总是返回一个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);
}
答案 3 :(得分:2)
HttpResponseException
派生自Exception
并嵌入HttpResponseMessage
。
由于它来自Exception
,因此在try
- catch
方案中非常有用。
HttpResponseException
返回的默认状态代码为HttpStatusCode.InternalServerError
。
答案 4 :(得分:0)
正如原始问题所述,返回的响应没有真正的区别。
HttpResponseException的真正目的是允许子方法创建和抛出&#39;他们自己的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通过动作调用堆栈冒泡,不会被正常的异常处理程序捕获并返回它的HttpResponseMessage,就像动作方法本身一样。