Après avoir examiné un article Traitement des exceptions dans l'API Web ASP.NET Je suis un peu confus quant au moment où il faut lancer une exception ou renvoyer une réponse d'erreur. Je me demande également s'il est possible de modifier la réponse lorsque votre méthode renvoie un modèle spécifique au domaine au lieu de HttpResponseMessage
...
Donc, pour résumer, voici mes questions suivies d'un code avec des numéros de cas :
Questions
Questions concernant le cas n°1
- Dois-je toujours utiliser
HttpResponseMessage
au lieu d'un modèle de domaine concret, afin que le message puisse être personnalisé ? - Le message peut-il être personnalisé si vous renvoyez un modèle de domaine concret ?
Questions concernant les cas n° 2, 3 et 4
- Devrais-je lancer une exception ou renvoyer une réponse d'erreur ? Si la réponse est "ça dépend", pouvez-vous donner des situations/exemples où il faut utiliser l'un ou l'autre ?
- Quelle est la différence entre jeter
HttpResponseException
vsRequest.CreateErrorResponse
? La sortie vers le client semble identique... - Dois-je toujours utiliser
HttpError
pour "envelopper" les messages de réponse dans les erreurs (que l'exception soit levée ou que la réponse à l'erreur soit renvoyée) ?
Exemples de cas
// 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;
}
Mise à jour
Pour mieux illustrer les cas 2, 3 et 4, l'extrait de code suivant présente plusieurs options qui peuvent se produire lorsqu'un client est introuvable...
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);
}