Il semble que vous ayez plus de difficultés avec la Validation qu'avec les erreurs/exceptions donc je vais en dire un peu sur les deux.
Validation
Les actions du contrôleur devraient généralement prendre des modèles d'entrée où la validation est déclarée directement sur le modèle.
public class Customer
{
[Require]
public string Name { get; set; }
}
Ensuite, vous pouvez utiliser un ActionFilter
qui envoie automatiquement des messages de validation au client.
public class ValidationActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var modelState = actionContext.ModelState;
if (!modelState.IsValid) {
actionContext.Response = actionContext.Request
.CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
}
}
}
Pour plus d'informations à ce sujet, consultez http://ben.onfabrik.com/posts/automatic-modelstate-validation-in-aspnet-mvc
Gestion des erreurs
Il est préférable de renvoyer un message au client qui représente l'exception survenue (avec le code d'état pertinent).
Par défaut, vous devez utiliser Request.CreateErrorResponse(HttpStatusCode, message)
si vous souhaitez spécifier un message. Cependant, cela lie le code à l'objet Request
, ce que vous ne devriez pas avoir à faire.
Je crée généralement mon propre type d'exception "sécurisé" que je m'attends à ce que le client sache gérer et j'enveloppe toutes les autres avec une erreur générique 500.
L'utilisation d'un filtre d'actions pour gérer les exceptions ressemblerait à ceci :
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exception = context.Exception as ApiException;
if (exception != null) {
context.Response = context.Request.CreateErrorResponse(exception.StatusCode, exception.Message);
}
}
}
Ensuite, vous pouvez l'enregistrer globalement.
GlobalConfiguration.Configuration.Filters.Add(new ApiExceptionFilterAttribute());
Il s'agit de mon type d'exception personnalisé.
using System;
using System.Net;
namespace WebApi
{
public class ApiException : Exception
{
private readonly HttpStatusCode statusCode;
public ApiException (HttpStatusCode statusCode, string message, Exception ex)
: base(message, ex)
{
this.statusCode = statusCode;
}
public ApiException (HttpStatusCode statusCode, string message)
: base(message)
{
this.statusCode = statusCode;
}
public ApiException (HttpStatusCode statusCode)
{
this.statusCode = statusCode;
}
public HttpStatusCode StatusCode
{
get { return this.statusCode; }
}
}
}
Un exemple d'exception que mon API peut générer.
public class NotAuthenticatedException : ApiException
{
public NotAuthenticatedException()
: base(HttpStatusCode.Forbidden)
{
}
}
1 votes
Voir stackoverflow.com/a/22163675/200442 vous devriez utiliser
ModelState
.1 votes
Notez que les réponses ici ne couvrent que les exceptions qui sont lancées dans le contrôleur lui-même. Si votre API renvoie un IQueryable qui n'a pas encore été exécuté, l'exception n'est pas dans le contrôleur et n'est pas attrapée...
4 votes
Très belle question mais je ne trouve pas de surcharge de constructeur de la classe
HttpResponseException
qui prend deux paramètres comme mentionné dans votre publication -HttpResponseException("Le nom du client ne peut pas être vide", HttpStatusCode.BadRequest)
c'est-à-direHttpResponseException(string, HttpStatusCode)
.