2016-03-14 30 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) 
    { 
    }