ASP .NET CORE simple parameter validation
13,660
Solution 1
You can create a custom filter attribute to instruct MVC pipeline to do the validation:
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));
}
}
}
}
}
Then add it to the action:
[HttpGet("test/{type}")]
[ValidateActionParameters]
public ActionResult GetSomeData([Range(0, 2)]byte type)
{
if (!ModelState.IsValid)
{
// isValid has correct value
}
}
Solution 2
As of version 2.1, this functionality is now available out of the box; data annotations on action parameters will also be respected when calling ModelState.IsValid
in the same way that they are on models.
If you annotate your class with the ApiController
attribute, validation will also be performed automatically, and a 400 Bad Request will be returned with details of the invalid data without having to call ModelState.IsValid
yourself.
Related videos on Youtube
Author by
Kane
Updated on June 04, 2022Comments
-
Kane almost 2 years
Is it 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 } ... }
When you call
/controller/test/4
,IsValid
is alwaysTRUE
.Is there a cleaner way to do that?
-
thisextendsthat over 5 yearsTake a look at
FluentValidation
- github.com/JeremySkinner/FluentValidation
-
-
zameb about 4 yearsThis answer helped me a lot. Also worth to mention that you can set the compatibility to a different version with services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); and you can also set the behavior of parameters (a "top level node") with services.AddMvc(options => { options.AllowValidatingTopLevelNodes = false; }); both in Startup.ConfigureServices method
-
Jeff Mercado over 3 yearsLooks like the code was swiped from here: blog.markvincze.com/…