自定义JsonConverter序列化返回空值,如何实现敏感字段掩码输出
问题原因
- 递归调用导致序列化异常:你的
CanConvert方法返回true,意味着所有类型都会使用该转换器。当在WriteJson中调用serializer.Serialize(writer, value)时,会再次触发当前转换器的WriteJson方法,陷入无限递归,最终输出空对象{}。 - 污染原始对象:直接修改
value的属性值会改变原始Student实例的状态,日志记录属于只读操作,这种修改可能影响后续业务逻辑。 - 多余的对象标记:手动调用
writer.WriteStartObject()和writer.WriteEndObject()后,serializer.Serialize又会写入一层对象标记,导致结构嵌套错误。
解决方案
以下是修正后的JsonConverter实现,既解决序列化异常,又避免污染原始数据:
public class StudentJsonConverter : JsonConverter { private readonly string[] _targetFields; public StudentJsonConverter(string[] targetFields) { _targetFields = targetFields; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // 将对象转换为JObject,不修改原始实例 var jObject = JObject.FromObject(value, serializer); foreach (var field in _targetFields) { if (jObject.TryGetValue(field, StringComparison.OrdinalIgnoreCase, out var token) && token.Type == JTokenType.String) { string originalValue = token.Value<string>(); jObject[field] = string.IsNullOrWhiteSpace(originalValue) ? null : new string('*', originalValue.Length); } } // 将处理后的JObject写入输出 jObject.WriteTo(writer); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException("该转换器仅用于日志序列化,不支持反序列化"); } public override bool CanConvert(Type objectType) { // 仅处理Student类型,避免递归调用 return objectType == typeof(Student); } }
关键修改点
- 使用JObject中转:通过
JObject.FromObject将对象序列化为中间对象,修改掩码后再写入输出,完全不影响原始Student实例。 - 限制转换器适用范围:
CanConvert仅返回Student类型的true,避免递归调用当前转换器。 - 移除多余的对象标记:依赖
JObject.WriteTo自动处理对象的开始和结束标记,避免结构错误。
运行修正后的代码,输出将符合预期:{"Name":"****","Phone":"1234"}
内容的提问来源于stack exchange,提问作者vic
相关产品推荐
相关产品推荐

