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

.NET 8自定义JsonConverter的Read方法未触发原因排查

问题分析与解决方案

核心问题1:Read方法未执行的原因

虽然EmailadressenConverter.CanConvert返回true,但序列化器未调用Read方法,大概率是因为转换器的注册优先级或类型匹配的隐性问题。默认情况下,JsonConverter<Emails>的CanConvert基类实现仅匹配typeof(Emails),但在处理可空引用类型(Emails?)时,可能存在序列化器的隐性判断偏差。此外,如果序列化器认为可以通过构造函数直接绑定类型(即使实际无法完成),也会跳过转换器。

核心问题2:转换器逻辑与JSON结构不匹配

你的JSON结构是嵌套的{"email": {"value":"foo@bar.com"}},但转换器代码中一直在查找Emailadressen.PrimairEmailAdres字段(该类未在代码中定义),完全无法匹配实际JSON结构,即便Read方法执行,也会返回null。


修复步骤

1. 修正转换器的CanConvert方法

显式指定匹配类型,消除隐性判断问题:

public override bool CanConvert(Type typeToConvert)
{
    // 明确匹配Emails类型,包括可空引用类型(运行时与非可空一致)
    return typeToConvert == typeof(Emails);
}

2. 重写Read方法适配JSON结构

根据实际JSON的嵌套结构,调整解析逻辑:

public override Emails? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
    if (reader.TokenType != JsonTokenType.StartObject)
        return null;

    string? emailValue = null;

    while (reader.Read())
    {
        if (reader.TokenType == JsonTokenType.EndObject)
            break;

        if (reader.TokenType == JsonTokenType.PropertyName)
        {
            var propName = reader.GetString();
            // 匹配外层的"email"属性
            if (string.Equals(propName, nameof(Emails.Email), StringComparison.CurrentCultureIgnoreCase))
            {
                // 进入email对象
                if (reader.Read() && reader.TokenType == JsonTokenType.StartObject)
                {
                    while (reader.Read())
                    {
                        if (reader.TokenType == JsonTokenType.EndObject)
                            break;

                        if (reader.TokenType == JsonTokenType.PropertyName)
                        {
                            var innerPropName = reader.GetString();
                            // 匹配内层的"value"属性
                            if (string.Equals(innerPropName, nameof(Emailadres.Value), StringComparison.CurrentCultureIgnoreCase))
                            {
                                if (reader.Read() && reader.TokenType == JsonTokenType.String)
                                {
                                    emailValue = reader.GetString();
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return string.IsNullOrEmpty(emailValue) ? null : new Emails(emailValue);
}

3. 修正测试代码中的JSON字符串

原代码中的JSON字符串写法存在语法错误,改为逐字字符串避免转义问题:

var json = @"{
    ""emailZakelijk"": {
        ""email"": {
            ""value"":""foo@bar.com""
        }
    }
}";

4. 强制转换器生效(可选)

如果仍存在转换器未被调用的情况,可以直接在Emails类上标记转换器属性,绕过全局注册的潜在问题:

[JsonConverter(typeof(EmailadressenConverter))]
public class Emails
{
    public Emails(string primairEmailadres)
    {
        Email = new Emailadres(primairEmailadres);
    }

    public Emailadres Email { get; set; }
}

内容的提问来源于stack exchange,提问作者Martijn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:30:55