2012-08-10 14 views
5

Quería crear un atributo de valdiation global para mi API web. Así que he seguido el tutorial y terminó con el siguiente atributo:Error de ASP.NET MVC 4 RC Web API ModelState para los parámetros de url opcionales que son anulables

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

Luego añade a fitlers globales en el Global.asax:

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

Funciona muy bien con la mayoría de mis acciones pero no como se esperaba con acciones que tienen parámetros de solicitud opcionales y anulables.

Por ejemplo:

creé una ruta:

y una acción en mi 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)); 
} 

Ahora, cuando solicito esta url: http://locahost/api/products tengo la respuesta con el código de estado 403 y el siguiente contenido:

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

Creo que esto no debería aparecer como un error de validación, ya que estos parámetros son opcionales y pueden contener nulos.

¿Alguien ha encontrado este problema y ha encontrado una solución?

Respuesta

2

parecen Estás en mal estado su código entre el API Web y MVC, se debe utilizar RouteParameter de API Web en lugar de UrlParameter de MVC

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

Pero:

Los parámetros por defecto de su ruta omitir y tomar no juegan ningún papel para su mecanismo de ruta porque solo los usa en la cadena de consulta, no en la plantilla de ruta. Por lo que la ruta más correctiva debe ser:

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

Buen punto, pero aún así no se soluciona el problema aquí. Ambos parámetros son "obligatorios" y tienen errores en el diccionario ModelState a pesar de que pueden contener nulos. ¿Conoces una manera de marcar un parámetro de acción como no requerido? –

+0

¿Has probado esta solución en tu código? –

+0

En cuanto a su pregunta, use los parámetros opcionales –

4

También es posible que desee evitar la validación de modelos/suprimir para los tipos primitivos de petición GET ..

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

¿Puedes elaborar? –

Cuestiones relacionadas