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

C#中JsonSerializer.Deserialize遇带引号的null字符串反序列化失败

处理JSON中带引号的"null"字符串反序列化问题

问题场景

从外部Web服务获取两种JSON格式:

  • 正常配置格式(config为对象):
{"config":{"c1":"All","c2":"is peachy"},"message":"We found a config object"}
  • 配置为空的格式(config为字符串"null"):
{"config":"null","message":"Config is null"}

需要将这些JSON反序列化为以下C#类型:

public class WebResponse
{     
   [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]   
   public Config Config { get; set; }  
   public string Message { get; set; } 
}

public class Config
{
    public string C1 { get; set; }
    public string C2 { get; set; }
}

使用System.Text.Json默认反序列化配置时,能正常处理第一种JSON,但处理第二种时会抛出DeserializeUnableToConvertValue异常——因为默认逻辑会把字符串"null"当成string类型,无法转换为Config对象。

解决方案:自定义JSON转换器

通过实现JsonConverter<Config>来处理这种特殊情况:当遇到字符串"null"时,返回null的Config实例;否则正常反序列化Config对象。

1. 实现自定义转换器

public class ConfigConverter : JsonConverter<Config>
{
    public override Config Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 如果当前JSON token是字符串类型
        if (reader.TokenType == JsonTokenType.String)
        {
            string value = reader.GetString();
            // 判断字符串是否为"null",是则返回null
            if (string.Equals(value, "null", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }
        }
        // 其他情况正常反序列化为Config对象
        return JsonSerializer.Deserialize<Config>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, Config value, JsonSerializerOptions options)
    {
        // 序列化逻辑按默认处理即可
        JsonSerializer.Serialize(writer, value, options);
    }
}

2. 应用转换器

有两种方式可以应用这个转换器:

方式一:添加到JsonSerializerOptions

var options = new JsonSerializerOptions
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    PropertyNameCaseInsensitive = true,
    // 注册自定义转换器
    Converters = { new ConfigConverter() }
};

// 处理带"null"字符串的JSON
string jsonNoConfig = @"{""config"":""null"",""message"":""Config is null""}";
WebResponse webResponseNoConfig = JsonSerializer.Deserialize<WebResponse>(jsonNoConfig, options);

// 处理正常配置的JSON
string jsonWithConfig = @"{""config"":{""c1"":""All"",""c2"":""is peachy""},""message"":""We found a config object""}";
WebResponse webResponseWithConfig = JsonSerializer.Deserialize<WebResponse>(jsonWithConfig, options);

方式二:给Config属性添加特性

直接在WebResponse的Config属性上标记转换器:

public class WebResponse
{     
   [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
   [JsonConverter(typeof(ConfigConverter))]   
   public Config Config { get; set; }  
   public string Message { get; set; } 
}

这种方式不需要修改JsonSerializerOptions,反序列化代码可以保持原有逻辑。

效果验证

添加转换器后,两种JSON格式都能正常反序列化:

  • 对于"config":"null",WebResponse.Config会被设置为null
  • 对于正常的config对象,WebResponse.Config会被正确实例化并赋值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:30:54