Dopo aver esaminato un articolo Gestione delle eccezioni nell'API Web ASP.NET, sono un po 'confuso su quando lanciare un'eccezione e restituire una risposta di errore. Mi chiedo anche se è possibile modificare la risposta quando il metodo restituisce un modello specifico di dominio anziché HttpResponseMessage
...
Quindi, per ricapitolare qui sono le mie domande seguite da un codice con i casi #:
Domande
Domande relative al caso n. 1
- Devo usare sempre
HttpResponseMessage
anziché un modello di dominio concreto, in modo che il messaggio possa essere personalizzato? - È possibile personalizzare il messaggio se si restituisce un modello di dominio concreto?
Domande relative al caso n. 2,3,4
- Devo generare un'eccezione o restituire una risposta di errore? Se la risposta è "dipende", puoi fornire situazioni / esempi su quando usare l'uno contro l'altro.
- Qual'è la differenza tra throwing
HttpResponseException
vsRequest.CreateErrorResponse
? L'output al client sembra identico ... - Devo sempre utilizzare
HttpError
per "avvolgere" i messaggi di risposta in errori (se viene generata l'eccezione o restituita la risposta all'errore)?
Esempi di casi
// 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;
}
Aggiornare
Per aiutare a dimostrare ulteriormente i casi n. 2,3,4 il seguente frammento di codice evidenzia diverse opzioni che "possono accadere" quando non viene trovato un cliente ...
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);
}