You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 15:15:02