.NET Framework Newtonsoft.Json自定义必填属性异常消息方案
自定义Newtonsoft.Json必填属性缺失异常消息的解决方案
方法一:Web API全局异常过滤器
针对API端点自动处理反序列化的场景,通过自定义异常过滤器捕获JsonSerializationException并重构异常消息:
- 实现自定义异常过滤器
public class JsonRequiredExceptionFilter : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext context) { if (context.Exception is not JsonSerializationException jsonEx) return; var requiredPropRegex = new Regex(@"Required property '(.*)' not found in JSON.*"); var match = requiredPropRegex.Match(jsonEx.Message); if (!match.Success) return; var propName = match.Groups[1].Value; // 从Action参数中获取目标DTO类型 var targetParam = context.ActionContext.ActionDescriptor.GetParameters() .FirstOrDefault(p => p.ParameterType.IsClass && !p.ParameterType.IsAbstract); var typeName = targetParam?.ParameterType.Name.ToLower() ?? "object"; var customMessage = $"Unable to create {typeName}, '{propName}' is required."; context.Response = context.Request.CreateErrorResponse( HttpStatusCode.BadRequest, customMessage, jsonEx); } }
- 在Web API配置中注册过滤器
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Filters.Add(new JsonRequiredExceptionFilter()); // 保留原有Json序列化配置 config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } }
方法二:自定义ContractResolver(通用场景)
如果需要在所有Newtonsoft.Json反序列化场景生效(包括非Web环境),可以通过重写ContractResolver替换必填属性的验证逻辑:
- 实现自定义ContractResolver
public class CustomRequiredContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); if (property.Required != Required.Always) return property; // 包装原有验证逻辑,替换异常消息 var originalValidator = property.RequiredValidator; property.RequiredValidator = (obj, serializer) => { try { originalValidator?.Invoke(obj, serializer); } catch (JsonSerializationException ex) { var typeName = obj.GetType().Name.ToLower(); var customMessage = $"Unable to create {typeName}, '{property.PropertyName}' is required."; throw new JsonSerializationException(customMessage, ex); } }; return property; } }
- 全局配置序列化设置(Web API示例)
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CustomRequiredContractResolver(); } }
关键说明
- 方法一依赖Web API的异常过滤体系,适合Web场景,可通过Action参数动态识别目标类型生成对应消息。
- 方法二是通用方案,不依赖Web框架,任何使用Newtonsoft.Json的反序列化操作都会触发自定义异常消息。
- 两种方案均保留原始异常的堆栈信息,既对外返回友好提示,也不影响后端调试。
内容的提问来源于stack exchange,提问作者Wouter Vandenputte
相关产品推荐
相关产品推荐

