Po przejrzeniu artykułu Obsługa wyjątków w ASP.NET Web API jestem trochę zdezorientowany, kiedy zgłosić wyjątek, a kiedy zwrócić odpowiedź na błąd. Zastanawiam się również, czy można zmodyfikować odpowiedź, gdy metoda zwraca model specyficzny dla domeny zamiast HttpResponseMessage
...
Podsumowując, oto moje pytania, po których następuje kod z numerami przypadków:
pytania
Pytania dotyczące przypadku nr 1
- Czy należy zawsze używać
HttpResponseMessage
zamiast konkretnego modelu domeny, aby można było dostosować wiadomość? - Czy można dostosować wiadomość, jeśli zwracasz konkretny model domeny?
Pytania dotyczące przypadku # 2, 3, 4
- Czy powinienem zgłaszać wyjątek lub zwracać odpowiedź na błąd? Jeśli odpowiedź brzmi „to zależy”, czy możesz podać sytuacje / przykłady, kiedy należy używać jednej lub drugiej.
- Jaka jest różnica między rzucaniem
HttpResponseException
a rzucaniemRequest.CreateErrorResponse
? Dane wyjściowe dla klienta wydają się identyczne ... - Czy powinienem zawsze
HttpError
„zawijać” komunikaty odpowiedzi błędami (niezależnie od tego, czy zostanie zgłoszony wyjątek, czy zwrócona odpowiedź na błąd)?
Przykłady przypadków
// 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;
}
Aktualizacja
Aby lepiej przedstawić przypadki # 2, 3, 4, poniższy fragment kodu podkreśla kilka opcji, które „mogą się zdarzyć”, gdy klient nie zostanie znaleziony ...
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);
}