2012-08-10 16 views
5

Volevo creare un attributo di valdiazione globale per la mia API Web. Così ho seguito la tutorial e si è conclusa con il seguente attributo:ASP.NET MVC 4 RC Web API Errore ModelState per i parametri facoltativi dell'URL che sono nullable

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); 
    } 
} 

poi ho aggiunto a fitlers globali nel Global.asax:

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

È perfettamente compatibile con la maggior parte delle mie azioni ma non come previsto con azioni che hanno parametri di richiesta facoltativi e nullable.

Ad esempio:

ho creato un percorso:

E un'azione nel mio 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)); 
} 

Ora, quando chiedo questo URL: http://locahost/api/products ottengo la risposta con 403 codice di stato e il seguente contenuto:

[ 
{ 
    "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." 
} 
] 

Credo che questo non dovrebbe apparire come un errore di convalida poiché questi parametri sono sia opzionali che annulli.

Qualcuno ha riscontrato questo problema e trovato una soluzione?

risposta

2

sembrerà incasinato il codice tra le API Web e MVC, è necessario utilizzare RouteParameter da API Web invece di UrlParameter da MVC

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

Ma:

I parametri di default del vostro route skip e take non svolgono alcun ruolo per il meccanismo del percorso perché vengono semplicemente utilizzati nella stringa di query, non nel modello di percorso. Così il percorso più correttiva dovrebbe essere:

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

Buon punto, ma ancora non risolve il problema Qui. Entrambi i parametri sono "obbligatori" e presentano errori nel dizionario ModelState nonostante siano annullabili. Conosci un modo per contrassegnare un parametro di azione come non richiesto? –

+0

Hai provato questa soluzione nel tuo codice? –

+0

Per quanto riguarda la tua domanda, usa i parametri opzionali –

4

Si consiglia inoltre di evitare/sopprimere la validazione dei modelli per i tipi primitivi in ​​richiesta GET ..

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

Puoi elaborare? –

Problemi correlati