2012-08-10 8 views
5

Ich wollte ein globales Validierungsattribut für meine Web-API erstellen. So folgte ich die tutorial und mit dem folgende Attribute endete:ASP.NET MVC 4 RC Web-API ModelState-Fehler für optionale URL-Parameter, die Nullwerte enthalten

public class ValidationActionFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     if (actionContext.ModelState.IsValid) 
     { 
      return; 
     } 

     var errors = new List<KeyValuePair<string, string>>(); 
     foreach (var key in actionContext.ModelState.Keys.Where(key => 
      actionContext.ModelState[key].Errors.Any())) 
     { 
      errors.AddRange(actionContext.ModelState[key].Errors 
        .Select(er => new KeyValuePair<string, string>(key, er.ErrorMessage))); 
     } 

     actionContext.Response = 
      actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors); 
    } 
} 

Dann habe ich es zu globalen fitlers im Global.asax:

configuration.Filters.Add(new ValidationActionFilter());

Es funktioniert gut mit den meisten meinen Aktionen aber nicht wie erwartet mit Aktionen, die optionale und nullable Request-Parameter haben.

Zum Beispiel:

ich eine Route erstellt:

Und eine Aktion in meine ProductsController:

public HttpResponseMessage GetAllProducts(int? skip, int? take) 
{ 
    var products = this._productService.GetProducts(skip, take, MaxTake); 

    return this.Request.CreateResponse(HttpStatusCode.OK, this._backwardMapper.Map(products)); 
} 

Nun, wenn ich bitte diese URL: http://locahost/api/products erhalte ich die Antwort mit 403 Statuscode und folgendem Inhalt:

[ 
{ 
    "Key": "skip.Nullable`1", 
    "Value": "A value is required but was not present in the request." 
}, 
{ 
    "Key": "take.Nullable`1", 
    "Value": "A value is required but was not present in the request." 
} 
] 

Ich glaube, dies sollte nicht als Validierungsfehler angezeigt werden, da diese Parameter sowohl optional als auch nullfähig sind.

Hat jemand dieses Problem gefunden und eine Lösung gefunden?

Antwort

2

Scheinen Sie Ihren Code zwischen Web-API und MVC vermasselt, Sie Routeparameter von Web-API statt UrlParameter von MVC

routes.MapHttpRoute(
    name: "Optional parameters route", 
    routeTemplate: "api/{controller}", 
    defaults: new { skip = RouteParameter.Optional, take = RouteParameter.Optional } 
    ); 

Aber verwenden sollte:

Die Standardparameter Ihrer Route überspringen und nehmen Sie spielen Sie keine Rolle für Ihre Route-Mechanismus, weil Sie nur sie in Query-String, nicht in Route-Vorlage verwenden. Also die meisten Korrektur Route sollte sein:

routes.MapHttpRoute(
    name: "Optional parameters route", 
    routeTemplate: "api/{controller}" 
    ); 
+1

Guter Punkt, aber immer noch ist es nicht lösen das Problem Hier. Beide Parameter sind "erforderlich" und weisen im ModelState-Wörterbuch Fehler auf, obwohl sie nullfähig sind. Kennen Sie eine Möglichkeit, einen Aktionsparameter als nicht erforderlich zu kennzeichnen? –

+0

Haben Sie diese Lösung in Ihrem Code ausprobiert? –

+0

Wie für Ihre Frage, verwenden Sie optionale Parameter –

4

Sie auch für primitive Typen in GET-Anfrage vermeiden/Unterdrückungs-Modellvalidierung möchten ..

public class ModelValidationFilter : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(HttpActionContext actionContext) 
     { 
      if (!actionContext.ModelState.IsValid && actionContext.Request.Method != HttpMethod.Get) 
      { ... 
+0

Können Sie es ausarbeiten? –

Verwandte Themen