{"record":{"id":"b960f5e3bc48f2f8","repo":"abpframework/abp","slug":"modelstate-is-not-valid-see-validationerrors-for","errorCode":null,"errorMessage":"ModelState is not valid! See ValidationErrors for details.","messagePattern":"ModelState is not valid! See ValidationErrors for details\\.","errorType":"validation","errorClass":"AbpValidationException","httpStatus":400,"severity":"error","filePath":"framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/ModelStateValidator.cs","lineNumber":19,"sourceCode":"﻿using System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing Microsoft.AspNetCore.Mvc.ModelBinding;\nusing Volo.Abp.DependencyInjection;\nusing Volo.Abp.Validation;\n\nnamespace Volo.Abp.AspNetCore.Mvc.Validation;\n\npublic class ModelStateValidator : IModelStateValidator, ITransientDependency\n{\n    public virtual void Validate(ModelStateDictionary modelState)\n    {\n        var validationResult = new AbpValidationResult();\n\n        AddErrors(validationResult, modelState);\n\n        if (validationResult.Errors.Any())\n        {\n            throw new AbpValidationException(\n                \"ModelState is not valid! See ValidationErrors for details.\",\n                validationResult.Errors\n            );\n        }\n    }\n\n    public virtual void AddErrors(IAbpValidationResult validationResult, ModelStateDictionary modelState)\n    {\n        if (modelState.IsValid)\n        {\n            return;\n        }\n\n        foreach (var state in modelState)\n        {\n            foreach (var error in state.Value.Errors)\n            {\n                validationResult.Errors.Add(new ValidationResult(error.ErrorMessage, new[] { state.Key }));","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/ModelStateValidator.cs#L1-L37","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: POST { \"age\": null } to DTO with [Required] int Age -> ModelState invalid\n// after: client sends { \"age\": 25 }","handlingStrategy":"validation","validationCode":"// On the client, validate before posting; on the server, inspect ModelState:\nif (!ModelState.IsValid)\n{\n    var errors = ModelState\n        .Where(kv => kv.Value?.Errors.Count > 0)\n        .Select(kv => $\"{kv.Key}: {kv.Value.Errors[0].ErrorMessage}\");\n    // return 400 with the specific field errors\n}","typeGuard":"null","tryCatchPattern":"try { modelStateValidator.Validate(ModelState); }\ncatch (AbpValidationException ex)\n{ /* ex.ValidationErrors -> return 400 details to client */ }","preventionTips":["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."],"tags":["validation","aspnetcore","modelstate","abp","api"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}