ASP .NET CORE simple parameter validation

Kan*_*ane 1 c# validation asp.net-core

I have implemented model validation in some of my APIs, but I was wondering if it is possible to do some validation using attributes on simple parameters, like:

[HttpGet("test/{type}")]
public ActionResult  GetSomeData([Range(0,2)]byte type)
{
  if (!ModelState.IsValid)
  {
    // isValid is always TRUE
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

When you call /controller/test/4, IsValid is always TRUE.

Is there a clean way to do that?

Thanks!

adr*_*ian 9

从 2.1 版开始,此功能现在开箱即用;ModelState.IsValid以与在模型上相同的方式调用时,动作参数上的数据注释也将受到尊重。

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-2.1#top-level-node-validation

如果你用ApiController属性注释你的类,验证也会自动执行,并且会返回一个 400 Bad Request,其中包含无效数据的详细信息,而无需调用ModelState.IsValid自己。

https://docs.microsoft.com/en-us/aspnet/core/web-api/index?view=aspnetcore-2.1#automatic-http-400-responses


Ale*_*bov 5

您可以创建一个自定义过滤器属性来指示MVC管道进行验证:

public class ValidateActionParametersAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var descriptor = context.ActionDescriptor as ControllerActionDescriptor;

        if (descriptor != null)
        {
            var parameters = descriptor.MethodInfo.GetParameters();

            foreach (var parameter in parameters)
            {
                var argument = context.ActionArguments[parameter.Name];

                EvaluateValidationAttributes(parameter, argument, context.ModelState);
            }
        }

        base.OnActionExecuting(context);
    }

    private void EvaluateValidationAttributes(ParameterInfo parameter, object argument, ModelStateDictionary modelState)
    {
        var validationAttributes = parameter.CustomAttributes;

        foreach (var attributeData in validationAttributes)
        {
            var attributeInstance = CustomAttributeExtensions.GetCustomAttribute(parameter, attributeData.AttributeType);

            var validationAttribute = attributeInstance as ValidationAttribute;

            if (validationAttribute != null)
            {
                var isValid = validationAttribute.IsValid(argument);
                if (!isValid)
                {
                    modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name));
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其添加到操作中:

[HttpGet("test/{type}")]
[ValidateActionParameters]
public ActionResult GetSomeData([Range(0, 2)]byte type)
{
    if (!ModelState.IsValid)
    {
       // isValid has correct value
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 看起来代码是从这里刷的:https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/ (2认同)