System.Text.Json自定义转换器如何获取属性名以筛选处理指定属性
解决方案(基于System.Text.Json实现)
首先明确:你提到的直接在自定义JsonConverter<string>的Read方法中判断reader.PropertyName == "Body"的写法不可行。因为当转换器的Read方法被触发时,Utf8JsonReader的指针已经移动到属性值的Token位置,属性名Token已经被序列化器提前读取,无法直接从reader实例中获取当前正在处理的属性名。
以下是3种可落地的实现方案,按推荐优先级排序:
方案1:属性级标注转换器(最推荐)
不需要修改转换器逻辑,也不会影响其他string类型属性,是性能最高、侵入性最低的方案。
你只需将原本全局注册的自定义string转换器,从JsonSerializerOptions.Converters集合中移除,直接标注到MyMailContent的Body属性上即可:
public class MyMailContent { // 其他属性不受影响,走默认string反序列化逻辑 public string Title { get; set; } public string Sender { get; set; } // 仅该属性使用自定义转换器处理 [JsonConverter(typeof(你自定义的String转换器类名))] public string Body { get; set; } }
方案2:契约动态绑定转换器(适用于.NET 7+,无需修改实体类)
如果你不能修改MyMailContent类的代码,可以用System.Text.Json 7及以上版本提供的「类型契约定制」功能,在序列化选项中动态给Body属性绑定自定义转换器:
var serializeOptions = new JsonSerializerOptions { TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => { // 只处理MyMailContent类的属性配置 if (typeInfo.Type != typeof(MyMailContent)) return; foreach (var prop in typeInfo.Properties) { // 找到Body属性就绑定自定义转换器 if (prop.Name.Equals(nameof(MyMailContent.Body), StringComparison.Ordinal)) { prop.CustomConverter = new 你自定义的String转换器类名(); } } } } } }; // 反序列化时传入上面的options即可 var result = await JsonSerializer.DeserializeAsync<MyMailContent>(stream, serializeOptions);
方案3:自定义MyMailContent类转换器(适用于需要全局控制反序列化逻辑的场景)
如果你必须在全局注册的转换器中做筛选,可以针对MyMailContent写专属的类转换器,在内部单独处理Body属性,其他属性走默认逻辑:
public class MyMailContentConverter : JsonConverter<MyMailContent> { public override MyMailContent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var result = new MyMailContent(); using var jsonDoc = JsonDocument.ParseValue(ref reader); var root = jsonDoc.RootElement; foreach (var jsonProp in root.EnumerateObject()) { var propertyInfo = typeof(MyMailContent).GetProperty(jsonProp.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); if (propertyInfo == null) continue; if (jsonProp.Name == nameof(MyMailContent.Body)) { // 这里写你自定义的Body属性反序列化逻辑 result.Body = CustomProcessBody(jsonProp.Value.GetString()); continue; } // 其他属性走默认反序列化逻辑 var propValue = JsonSerializer.Deserialize(jsonProp.Value.GetRawText(), propertyInfo.PropertyType, options); propertyInfo.SetValue(result, propValue); } return result; } public override void Write(Utf8JsonWriter writer, MyMailContent value, JsonSerializerOptions options) { // 序列化不需要自定义的话直接走默认逻辑即可 JsonSerializer.Serialize(writer, value, options); } }
使用时将这个类转换器注册到JsonSerializerOptions.Converters即可。
内容的提问来源于stack exchange,提问作者Asons
相关产品推荐
相关产品推荐

