Es sieht so aus, als hätten Sie mehr Probleme mit der Validierung als mit Fehlern/Ausnahmen, also werde ich ein wenig über beide sagen.
Validierung
Controller-Aktionen sollten im Allgemeinen Eingabemodelle verwenden, bei denen die Validierung direkt am Modell deklariert wird.
public class Customer
{
[Require]
public string Name { get; set; }
}
Dann können Sie eine ActionFilter
die automatisch Validierungsmeldungen an den Kunden zurücksendet.
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);
}
}
}
Weitere Informationen zu diesem Thema finden Sie unter http://ben.onfabrik.com/posts/automatic-modelstate-validation-in-aspnet-mvc
Fehlerbehandlung
Am besten ist es, eine Nachricht an den Client zurückzuschicken, die die aufgetretene Ausnahme darstellt (mit dem entsprechenden Statuscode).
Nach dem Auspacken müssen Sie Folgendes verwenden Request.CreateErrorResponse(HttpStatusCode, message)
wenn Sie eine Nachricht angeben möchten. Dies bindet den Code jedoch an den Request
Objekts, was Sie nicht tun müssen.
In der Regel erstelle ich eine eigene "sichere" Ausnahme, von der ich annehme, dass der Client weiß, wie sie zu behandeln ist, und verpacke alle anderen mit einem generischen 500-Fehler.
Die Verwendung eines Aktionsfilters zur Behandlung der Ausnahmen würde folgendermaßen aussehen:
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);
}
}
}
Dann können Sie es global registrieren.
GlobalConfiguration.Configuration.Filters.Add(new ApiExceptionFilterAttribute());
Dies ist mein benutzerdefinierter Ausnahmetyp.
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; }
}
}
}
Ein Beispiel für eine Ausnahme, die meine API auslösen kann.
public class NotAuthenticatedException : ApiException
{
public NotAuthenticatedException()
: base(HttpStatusCode.Forbidden)
{
}
}