System.Text.Json全局JsonConverter<string>处理xyz属性值失效求助
问题原因与解决方案
为什么原代码无法进入属性名判断逻辑
你写的CustomJsonConverter : JsonConverter<string>是专门处理string类型值的转换器。当System.Text.Json框架调用它时,已经完成了属性名的解析流程,Utf8JsonReader的位置已经跳到了属性对应的字符串值上,所以reader.TokenType必然是JsonTokenType.String,永远进不了判断JsonTokenType.PropertyName的分支。
解决方案一:全局配置精准匹配目标属性(推荐)
通过DefaultJsonTypeInfoResolver修改类型元数据,自动给所有名为xyz的string属性绑定自定义转换器,无需修改实体类、不用加特性标记。
代码实现
// 只负责处理字符串值修改的转换器 public class XyzStringConverter : JsonConverter<string> { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { string originalValue = reader.GetString(); // 这里写你的值修改逻辑 return $"Modified: {originalValue}"; } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { writer.WriteStringValue(value); } } // 全局配置 var _options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true, TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => { // 遍历当前类型的所有属性元数据 foreach (var property in typeInfo.Properties) { // 匹配string类型、属性名为xyz(忽略大小写,和配置一致) if (property.PropertyType == typeof(string) && string.Equals(property.Name, "xyz", StringComparison.OrdinalIgnoreCase)) { // 给该属性绑定自定义转换器 property.CustomConverter = new XyzStringConverter(); } } } } } }; // 反序列化使用 var result = await JsonSerializer.DeserializeAsync<T>(stream, _options);
解决方案二:对象级转换器手动解析
如果你的目标实体类型固定,或者需要更灵活的JSON解析控制,可以写一个针对对象类型的转换器,手动遍历属性名和值,找到xyz属性后修改其值。
代码实现(以MyClass为例)
public class MyClassConverter : JsonConverter<MyClass> { public override MyClass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var myClass = new MyClass(); if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException("JSON格式错误"); } while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return myClass; } if (reader.TokenType == JsonTokenType.PropertyName) { string propertyName = reader.GetString(); reader.Read(); // 移动到属性值位置 // 匹配xyz属性并处理 if (string.Equals(propertyName, "xyz", StringComparison.OrdinalIgnoreCase) && reader.TokenType == JsonTokenType.String) { string originalValue = reader.GetString(); myClass.xyz = $"Modified: {originalValue}"; } else { // 其他属性使用默认反序列化逻辑 var property = typeToConvert.GetProperty( propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); if (property != null) { object value = JsonSerializer.Deserialize(ref reader, property.PropertyType, options); property.SetValue(myClass, value); } } } } throw new JsonException("JSON解析未完成"); } public override void Write(Utf8JsonWriter writer, MyClass value, JsonSerializerOptions options) { // 写入逻辑沿用默认序列化 JsonSerializer.Serialize(writer, value, options); } } // 全局配置添加对象转换器 var _options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true, Converters = { new MyClassConverter() } };
内容的提问来源于stack exchange,提问作者dnxit
相关产品推荐
相关产品推荐

