abpframework/abp · error · AbpValidationException
ModelState is not valid! See ValidationErrors for details.
Error message
ModelState is not valid! See ValidationErrors for details.
What it means
Thrown by ModelStateValidator.Validate after it collects all ASP.NET Core ModelStateDictionary errors into an AbpValidationResult. If any model-binding/validation errors exist, it raises AbpValidationException with this message and the collected errors as ValidationErrors. This is the ABP pipeline's central translation of ASP.NET Core model-state failures into ABP's exception/filter format.
Source
Thrown at framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/ModelStateValidator.cs:19
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Validation;
namespace Volo.Abp.AspNetCore.Mvc.Validation;
public class ModelStateValidator : IModelStateValidator, ITransientDependency
{
public virtual void Validate(ModelStateDictionary modelState)
{
var validationResult = new AbpValidationResult();
AddErrors(validationResult, modelState);
if (validationResult.Errors.Any())
{
throw new AbpValidationException(
"ModelState is not valid! See ValidationErrors for details.",
validationResult.Errors
);
}
}
public virtual void AddErrors(IAbpValidationResult validationResult, ModelStateDictionary modelState)
{
if (modelState.IsValid)
{
return;
}
foreach (var state in modelState)
{
foreach (var error in state.Value.Errors)
{
validationResult.Errors.Add(new ValidationResult(error.ErrorMessage, new[] { state.Key }));View on GitHub (pinned to 7ed43b1931)
Solutions
- Inspect the ValidationErrors collection (or the ABP exception's data) to see exactly which fields failed and why.
- Fix the client request to satisfy the data-annotation / type constraints on the DTO.
- Add or correct [Required], [Range], [StringLength], etc. so the contract is explicit.
- If validation is unexpected, check that model binders and JSON serialization options match the DTO types.
Example fix
// before: POST { "age": null } to DTO with [Required] int Age -> ModelState invalid
// after: client sends { "age": 25 } Defensive patterns
Strategy: validation
Validate before calling
// On the client, validate before posting; on the server, inspect ModelState:
if (!ModelState.IsValid)
{
var errors = ModelState
.Where(kv => kv.Value?.Errors.Count > 0)
.Select(kv => $"{kv.Key}: {kv.Value.Errors[0].ErrorMessage}");
// return 400 with the specific field errors
} Type guard
null
Try / catch
try { modelStateValidator.Validate(ModelState); }
catch (AbpValidationException ex)
{ /* ex.ValidationErrors -> return 400 details to client */ } Prevention
- Define explicit data-annotation attributes on every DTO field.
- Validate on the client (FluentValidation / unobtrusive) mirroring server rules.
- Return field-level errors so the client can fix inputs.
- Keep DTO types aligned with JSON serialization options.
When it happens
Trigger: Calling ModelStateValidator.Validate(modelState) (or letting ABP's MVC validation filter call it) on a request whose ModelStateDictionary.IsValid is false - i.e. a field failed data-annotations, model binding, or [ApiController] automatic validation.
Common situations: Sending a DTO with a missing [Required] field, a wrong type (string where int expected), out-of-range values, or malformed JSON that fails model binding; enabling ABP's auto-validation on a controller that receives invalid input.
Related errors
- Given tenant doesn't exist: {0}
- Given tenant isn't available: {0}
- Job args types cannot contain null.
- Invalid background job name filter mode: {mode}
- Job names must be empty when the filter mode is None.
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/b960f5e3bc48f2f8.
Report an issue: GitHub.