Commenting here because the solutions on here weren't right for my scenario, so just came up with my own solution instead.
This works for ASP.NET Framework 4.5.2, in an MVC5 web application. This code is by no means perfect as I threw it together very quickly for a proof of concept, but it does compile. You can remove the part where I return a BadRequest status code result and add the validation errors to the model state - or do whatever your requirements need.
First create a custom attribute class:
public class DataAnnotationFilterAttribute : ActionFilterAttribute, IResultFilter
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var actionParams = filterContext.ActionDescriptor.GetParameters();
if (actionParams != null)
{
foreach (var param in actionParams)
{
ValidationAttribute[] atts = (ValidationAttribute[])param.GetCustomAttributes(typeof(ValidationAttribute), false);
if (atts != null && filterContext.ActionParameters.TryGetValue(param.ParameterName, out object value))
{
foreach(ValidationAttribute att in atts)
{
if (!att.IsValid(value))
filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
}
}
}
}
base.OnActionExecuting(filterContext);
}
}
Then register your attribute in FilterConfig.cs, which should already be part of your project:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute()); // this was existing
filters.Add(new DataAnnotationFilterAttribute());
}
}
Now you can use attributes that inherit from the "ValidationAttribute" on your MVC action parameters.