Automatic ASP.NET Core Model Validation Using a Custom Action Filter
If you hate having to check for ModelState validation in all your controller actions, you're at the right place.
Create a custom ActionFilterAttribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ValidateModelStateFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
// For API endpoints, return JSON error response
if (IsApiController(context.Controller))
{
var errors = context.ModelState
.Where(x => x.Value?.Errors.Count > 0)
.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value?.Errors.Select(e => e.ErrorMessage).ToArray()
);
context.Result = new BadRequestObjectResult(new
{
Message = "Validation failed",
Errors = errors
});
}
else
{
// For MVC controllers, return view with model errors
context.Result = new ViewResult();
}
}
base.OnActionExecuting(context);
}
private static bool IsApiController(object controller)
{
return controller.GetType()
.GetCustomAttributes(typeof(ApiControllerAttribute), true).Length != 0;
}
}
And then decorate the controller or action method you want to validate with the [ValidateModelStateFilter] attribute
If you will like this applied to all your controllers then do this:
services.AddControllersWithViews(options =>
{
options.Filters.Add(new ValidateModelStateFilterAttribute()); // Custom model validation filter
});
This helps you avoid checking the ModelState in all your controller actions.