.NET Core 5中MaxModelValidationErrors设为1无法获取自定义验证错误如何解决
结论
直接返回ValidationResult("MY_ERROR")无法解决该问题,核心原因是默认模型验证的执行顺序和截断逻辑:
ASP.NET Core默认会先执行属性级的数据注解验证,所有属性验证完成后才会调用IValidatableObject的Validate方法。你设置MaxModelValidationErrors = 1时,如果属性级验证已经产生了1条错误,框架会直接终止验证流程,根本不会执行你的自定义Validate方法,自然收集不到你抛出的自定义错误,只会返回默认的最大错误数提示。
可行解决方案
你要避免执行不必要的数据库查询,推荐以下两种方案:
方案1:自行控制Validate方法的执行逻辑(最推荐)
不用依赖框架的MaxModelValidationErrors做终止控制,直接在Validate方法内部判断终止条件,触发后直接返回错误并中断后续逻辑,数据库查询代码完全不会执行:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { // 前置校验逻辑(无数据库查询) if (/* 触发错误的条件 */) { yield return new ValidationResult("MY_ERROR"); // 直接中断迭代,后续所有逻辑(包括数据库查询)都不会执行 yield break; } // 只有前置校验通过,才会执行后续的数据库验证逻辑 var dbContext = validationContext.GetService<你的DbContext类型>(); // 数据库查询逻辑 // ... }
同时你可以把MaxModelValidationErrors调整为更大的值(比如10),避免框架提前截断你的自定义错误。
方案2:自定义错误响应工厂,过滤默认提示
如果你必须保留MaxModelValidationErrors = 1的配置,可以自定义无效模型状态的响应逻辑,优先返回你的自定义错误、过滤默认的最大错误提示:
services.AddControllers(options => { options.MaxModelValidationErrors = 1; options.InvalidModelStateResponseFactory = context => { var errorList = context.ModelState.Values .SelectMany(v => v.Errors.Select(e => e.ErrorMessage)) .ToList(); // 存在自定义错误优先返回 var customError = errorList.FirstOrDefault(e => e == "MY_ERROR"); if (customError != null) { return new BadRequestObjectResult(new { error = customError }); } // 其他错误逻辑 return new BadRequestObjectResult(new { errors = errorList }); }; });
内容的提问来源于stack exchange,提问作者avechuche
相关产品推荐
相关产品推荐

