使用JsonIgnore导致社会保障号无法传入API,寻求敏感字段通用处理方案
解决Newtonsoft.Json敏感字段序列化忽略、反序列化正常取值的通用方案
[JsonIgnore]默认同时作用于序列化、反序列化两个阶段,所以直接使用会导致POST请求反序列化时SSN字段被忽略,取值为null。你需要的是仅在接口返回序列化阶段屏蔽敏感字段,反序列化接收参数时正常解析,以下是两种可落地的通用方案:
方案1:自定义敏感字段特性+全局契约解析器(推荐,适合多实体多敏感字段场景)
该方案无业务侵入,所有需要屏蔽的敏感字段仅需加一个标记即可,复用性强:
- 定义敏感字段标记特性
/// <summary> /// 标记敏感数据字段,序列化时自动忽略 /// </summary> [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class SensitiveDataAttribute : Attribute { }
- 自定义Newtonsoft契约解析器,控制标记字段的序列化逻辑
public class SensitiveDataFilterContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 标记了[SensitiveData]的字段,仅禁止序列化,反序列化不受影响 if (Attribute.IsDefined(member, typeof(SensitiveDataAttribute))) { property.ShouldSerialize = instance => false; } return property; } }
- 全局配置Newtonsoft使用该契约解析器
以ASP.NET Core项目为例,在Program.cs中配置:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new SensitiveDataFilterContractResolver(); });
- 在DTO中给敏感字段加标记即可
public class UserPostDto { public string UserName { get; set; } [SensitiveData] public string SSN { get; set; } // 其他敏感字段直接加特性即可,无需额外修改 [SensitiveData] public string IdCardNumber { get; set; } [SensitiveData] public string BankCardNo { get; set; } }
方案2:使用原生条件序列化方法(无需全局配置,适合少量实体场景)
Newtonsoft会自动识别DTO中命名为ShouldSerialize{属性名}的方法,返回false时该属性序列化时会被忽略,反序列化不受影响:
public class UserPostDto { public string UserName { get; set; } public string SSN { get; set; } public string IdCardNumber { get; set; } // 序列化时忽略SSN public bool ShouldSerializeSSN() => false; // 序列化时忽略身份证号 public bool ShouldSerializeIdCardNumber() => false; }
两种方案均满足:POST请求传入SSN等敏感字段时可以正常反序列化拿到值,接口返回时自动屏蔽敏感字段,不需要手动过滤。
内容的提问来源于stack exchange,提问作者Peter Trefren
相关产品推荐
相关产品推荐

