首页 文章

WebApi - 访问和验证过滤器中的模型

提问于
浏览
0

我创建了一个过滤器,用于从接收模型作为参数的操作中使用 . 想法是在请求到达动作本身之前返回400 .

这是过滤器:

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只是试图验证参数 . 如果我从方法声明中删除,那么 does 验证我的模型 .

有没有办法让ModelState验证这两个参数?

嗯......似乎ModelState does 甚至在方法声明中使用验证模型 . 唯一的问题是,如果发送了OrderNotification模型,我找不到一种方法来发现(在OnActionExecuting方法中) .

当我发送一个空的JSON时,ModelState.Values.Count为1,并且由于存在于URL中,因此ModelState.IsValid为true .

2 回答

  • 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)
      {
      }
    

相关问题