После просмотра статьи Обработка исключений в веб-API ASP.NET Я немного смущен, когда бросать исключение vs возвращать ошибку ответ. Мне также интересно узнать, можно ли изменить ответ, когда ваш метод возвращает модель, специфичную для домена, вместо HttpResponseMessage
...
Итак, напомню, вот мои вопросы, за которыми следует некоторый код с кодом #s:
Вопросы
Вопросы по делу № 1
- Должен ли я всегда использовать
HttpResponseMessage
вместо конкретной модели домена, чтобы сообщение можно было настроить? - Можно ли настроить сообщение, если вы возвращаете конкретную модель домена?
Вопросы по делу № 2,3,4
- Должен ли я бросать исключение или возвращать ответ об ошибке? Если ответ "это зависит", можете ли вы дать ситуации/примеры того, когда использовать один против другого.
- В чем разница между бросанием
HttpResponseException
vsRequest.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;
}
Update
Чтобы еще раз продемонстрировать случаи # 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);
}