阅读了一个文章ASP.NET Web API异常处理后,我对何时抛出异常与返回错误响应感到有些困惑。当方法返回特定领域模型而非HttpResponseMessage
时,是否可以修改响应?
回顾一下,以下是我的问题和几个案例:
问题
关于案例#1的问题
- 是否应始终使用
HttpResponseMessage
而不是具体的领域模型,以便可以自定义消息? - 如果返回具体的领域模型,是否仍然可以自定义消息?
关于案例#2、3、4的问题
- 是否应该抛出异常或返回错误响应?如果答案是“取决于情况”,请举例说明何时使用其中之一。
- 抛出
HttpResponseException
与Request.CreateErrorResponse
有什么区别?对客户端的输出似乎相同... - 是否始终应使用
HttpError
将响应消息包装在错误中(无论是抛出异常还是返回错误响应)?
案例样本
// CASE #1
public Customer Get(string id)
{
var customer = _customerService.GetById(id);
if (customer == null)
{
var notFoundResponse = new HttpResponseMessage(HttpStatusCode.NotFound);
throw new HttpResponseException(notFoundResponse);
}
//var response = Request.CreateResponse(HttpStatusCode.OK, customer);
//response.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(300));
return customer;
}
// CASE #2
public HttpResponseMessage Get(string id)
{
var customer = _customerService.GetById(id);
if (customer == null)
{
var notFoundResponse = new HttpResponseMessage(HttpStatusCode.NotFound);
throw new HttpResponseException(notFoundResponse);
}
var response = Request.CreateResponse(HttpStatusCode.OK, customer);
response.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(300));
return response;
}
// CASE #3
public HttpResponseMessage Get(string id)
{
var customer = _customerService.GetById(id);
if (customer == null)
{
var message = String.Format("customer with id: {0} was not found", id);
var errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
throw new HttpResponseException(errorResponse);
}
var response = Request.CreateResponse(HttpStatusCode.OK, customer);
response.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(300));
return response;
}
// CASE #4
public HttpResponseMessage Get(string id)
{
var customer = _customerService.GetById(id);
if (customer == null)
{
var message = String.Format("customer with id: {0} was not found", id);
var httpError = new HttpError(message);
return Request.CreateErrorResponse(HttpStatusCode.NotFound, httpError);
}
var response = Request.CreateResponse(HttpStatusCode.OK, customer);
response.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddSeconds(300));
return response;
}
更新
为了更好地演示情况#2、3和4,以下代码片段突出几个可能发生的选项,当客户没有找到时......
if (customer == null)
{
// which of these 4 options is the best strategy for Web API?
// option 1 (throw)
var notFoundMessage = new HttpResponseMessage(HttpStatusCode.NotFound);
throw new HttpResponseException(notFoundMessage);
// option 2 (throw w/ HttpError)
var message = String.Format("Customer with id: {0} was not found", id);
var httpError = new HttpError(message);
var errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, httpError);
throw new HttpResponseException(errorResponse);
// option 3 (return)
var message = String.Format("Customer with id: {0} was not found", id);
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
// option 4 (return w/ HttpError)
var message = String.Format("Customer with id: {0} was not found", id);
var httpError = new HttpError(message);
return Request.CreateErrorResponse(HttpStatusCode.NotFound, httpError);
}