ModelState用于检查Web Api中的所有参数

时间:2017-05-22 10:02:09

标签: asp.net-web-api

这是我的动作,ModelState只检查bookId参数。另一个即使它为null,也不会引发错误。

有没有办法让它检查所有参数的ModelState?

[HttpPut]
[Route("{bookId}")]
public IHttpActionResult Edit([FromBody] EditBookBindingModel model, int bookId)
{
    if (!this.service.ExistsBook(bookId))
    {
        return this.NotFound();
    }

    if (!this.ModelState.IsValid)
    {
        return this.StatusCode(HttpStatusCode.BadRequest);
    }

    this.service.EditBook(bookId, model);

    return this.Ok();
}

2 个答案:

答案 0 :(得分:0)

您可以定义一个ActionFilterAttribute来保护您免受空参数的攻击:

public class CheckModelForNullAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ActionArguments.ContainsValue(null))
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "The argument cannot be null");
    }
}

然后使用:

[HttpPut]
[Route("{bookId}")]
[CheckModelForNull]
public IHttpActionResult Edit([FromBody] EditBookBindingModel model, int bookId)
{
    // model can´t be null now
    ...

答案 1 :(得分:0)

我编写了一个自定义过滤器,因此DataAnnotations也可以使用参数。 这是过滤器。

    public class ModelValidationFilter : FilterAttribute, IActionFilter, IFilter
{
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext,
    CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{

    var parameters = actionContext.ActionDescriptor.GetParameters();

    if (parameters.Any())
    {
        var validationParams = parameters.Where(x => x.GetCustomAttributes<ValidationAttribute>().Any());

        if (validationParams.Any())
        {
            foreach (var item in validationParams)
            {
                var val = actionContext.ActionArguments[item.ParameterName];

                foreach (var attr in item.GetCustomAttributes<ValidationAttribute>())
                {
                    if (!attr.IsValid(val))
                    {
                        actionContext.ModelState.AddModelError(item.ParameterName, attr.FormatErrorMessage(item.ParameterName));
                    }
                }
            }
        }

        if (!actionContext.ModelState.IsValid)
        {
            return Task.FromResult(actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState));
        }
    }

    return continuation();
}
}

用法(我没有完全测试过。):

将其添加到全局过滤器。

config.Filters.Add(new ModelValidationFilter());
public Student Post([Required] addStudentDTO)
{
    //Your logic
}

public Student Patch([FromBody,Required] addStudentDTO, [Required,EmailAddress]string emailAddress])
{
    //Your logic
}