2016-03-14 3 views
0

Я создал фильтр, который будет использоваться из действий, которые получают Модели в качестве параметров. Идея состоит в том, чтобы вернуть 400 до того, как запрос поступит непосредственно в действие.WebApi - Доступ и проверка моделей в фильтрах

Вот фильтр:

public class ValidateModelAttribute : ActionFilterAttribute 
{ 
    private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     Log.Debug(""); 

     var _return = new BaseReturn<object>(); 
     _return.Success = false; 

     try 
     { 
      if (actionContext.ModelState.IsValid && actionContext.ActionArguments[actionContext.ActionArguments.Keys.First()] != null) 
       return; 

      if (actionContext.ModelState.Values.Count == 0) 
       _return.Message = "Model not sent"; 

      if (actionContext.ModelState.Values.Count > 0 && actionContext.ModelState.Values.Any(c => c.Errors.Count > 0)) 
       _return.Message = actionContext.ModelState.Values.First(c => c.Errors.Count > 0).Errors[0].ErrorMessage; 

     } 
     catch (Exception ex) 
     { 
      _return.Message = ex.Message; 
     } 

     if (_return.Message == null) 
      _return.Message = "Model is not valid"; 

     actionContext.Response = actionContext.Request.CreateResponse<BaseReturn<object>>(HttpStatusCode.BadRequest, _return); 
    } 
} 

И это мое действие:

[HttpPost] 
[Route("api/Devices/{id}/SendOrder")] 
[ValidateModel] 
public BaseReturn<bool> SendNotificationToDevice(string id, OrderNotification model) 
{ 
} 

Проблема здесь заключается в том, что ModelState только пытается проверить {ID} параметра. Это делает проверяет мою модель, если я удалю {id} из объявления метода.

Есть ли способ заставить ModelState проверить оба параметра?

Хорошо ... кажется, что ModelState делает проверяет модель даже на {id} в объявлении метода. Единственная проблема заключается в том, что я не смог найти способ обнаружить (в методе OnActionExecuting), если была отправлена ​​модель OrderNotification или нет.

Когда я отправляю пустой JSON, ModelState.Values.Count равен 1, и поскольку в URL-адресе присутствует {id}, ModelState.IsValid является true.

ответ

1

По умолчанию в ASP.NET Web API, null значения параметров объекта не считаются недействительными. Если вы хотите рассматривать их как недействительные, вы можете обновить свой фильтр, чтобы сначала обработать параметры, чтобы убедиться, что они имеют значение:

 foreach (var parameter in actionContext.ActionDescriptor.GetParameters()) 
     { 
      object parameterValue; 
      if (!parameter.IsOptional 
       && parameter.ParameterType.IsClass 
       && actionContext.ActionArguments.TryGetValue(parameter.ParameterName, 
       out parameterValue)) 
      { 
       if (parameterValue == null) 
       { 
        ModelState.AddModelError(parameter.ParameterName, ""); 
       } 
      } 
     } 
0

parameter-binding-in-aspnet-web-api

Чтобы заставить Web API читать сложный тип из URI, добавьте [FromUri] атрибут параметра

вы пытались добавить [FromUri] атрибут к вашему параметру?

[HttpPost] 
    [Route("api/Devices/{id}/SendOrder")] 
    [ValidateModel] 
    public BaseReturn<bool> SendNotificationToDevice(string id, [FromUri]OrderNotification model) 
    { 
    }