'ASP .NET CORE simple parameter validation
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 always TRUE
.
Is there a cleaner way to do that?
Solution 1:[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:[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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Alex Riabov |
Solution 2 | adrian |