如何区分ModelState验证错误类型:JSON格式与模型验证错误?
问题分析:为什么
Exception属性始终为null ASP.NET Core默认处理JSON反序列化错误时,不会将原始的JsonException实例直接挂载到ModelStateError.Exception上,而是会把反序列化错误信息解析后存入ErrorMessage字段,所以你通过Exception is JsonException筛选不到目标错误。
解决方案:区分JSON格式错误与模型验证错误
方法1:通过ModelStateEntry的Key区分
JSON反序列化错误(比如缺少逗号、格式非法)会被关联到根节点,对应的ModelStateEntry.Key为空字符串;而模型验证错误(比如必填字段缺失)的Key是具体的属性名(如"UserName")。
示例代码:
if (!ModelState.IsValid) { // 筛选JSON格式错误(Key为空的条目) var jsonErrors = ModelState.Where(kv => string.IsNullOrEmpty(kv.Key)) .SelectMany(kv => kv.Value.Errors) .ToList(); // 筛选模型验证错误(Key为具体属性名的条目) var modelValidationErrors = ModelState.Where(kv => !string.IsNullOrEmpty(kv.Key)) .SelectMany(kv => kv.Value.Errors) .ToList(); // 返回自定义错误 if (jsonErrors.Any()) { return BadRequest(new { Code = "JSON_FORMAT_ERROR", Message = "请求JSON格式非法,请检查语法" }); } else { var errorMessages = modelValidationErrors.Select(e => e.ErrorMessage); return BadRequest(new { Code = "MODEL_VALIDATION_FAILED", Messages = errorMessages }); } }
方法2:自定义配置让Exception属性生效
在Program.cs(或Startup.cs)中配置JsonOptions,让系统保留反序列化的原始异常:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; // 配置反序列化错误处理,保留原始异常 options.AllowInputFormatterExceptionMessages = true; });
配置完成后,你就能通过e.Exception is JsonException筛选JSON格式错误了,注意该配置会让错误信息包含更多技术细节,返回给前端前建议转换为友好提示。
方法3:通过错误信息特征补充判断
如果担心Key判断不够准确,可以结合错误信息的特征(比如JSON反序列化错误通常包含"JSON"、"反序列化"、"语法"等关键词),但这种方式不如Key判断可靠,仅作为补充:
var jsonErrors = errors.Where(e => e.ErrorMessage.Contains("JSON") || e.ErrorMessage.Contains("反序列化"));
内容的提问来源于stack exchange,提问作者okThen
相关产品推荐
相关产品推荐

