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

JSON反序列化为C#对象前校验属性值,解决None值转换报错问题

解决方案

方案1:全局配置JsonSerializerSettings(推荐)

一次性处理所有反序列化场景,无需提前对JSON字符串做替换操作:
首先自定义通用转换器处理None值,自动返回对应类型默认值:

public class NoneToDefaultConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => true;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // 匹配None或null值
        if (reader.Value?.ToString() == "None" || reader.TokenType == JsonToken.Null)
        {
            // 值类型返回默认值,引用类型返回null
            return objectType.IsValueType ? Activator.CreateInstance(objectType) : null;
        }

        // 兼容处理日期、数值类型的格式转换
        try
        {
            return Convert.ChangeType(reader.Value, objectType);
        }
        catch
        {
            return objectType.IsValueType ? Activator.CreateInstance(objectType) : null;
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // 仅需反序列化可直接抛出未实现异常
        throw new NotImplementedException();
    }
}

然后配置全局序列化设置:

var settings = new JsonSerializerSettings
{
    // 自动填充默认值
    DefaultValueHandling = DefaultValueHandling.Populate,
    // 注册自定义转换器
    Converters = { new NoneToDefaultConverter() }
};

// 直接反序列化即可,无需提前替换None
var quote = JsonConvert.DeserializeObject<Quote>(json, settings);

方案2:自定义属性单独配置字段

如果不需要全局生效,仅需要针对指定类的特定字段做处理,可以用泛型转换器加特性标记的方式实现:
首先定义泛型转换器:

public class NoneToDefaultConverter<T> : JsonConverter<T>
{
    public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.Value?.ToString() == "None" || reader.TokenType == JsonToken.Null)
        {
            return default(T);
        }
        try
        {
            return (T)Convert.ChangeType(reader.Value, typeof(T));
        }
        catch
        {
            return default(T);
        }
    }

    public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

给需要处理的属性加上JsonConverter特性即可:

public class Quote
{
    [JsonConverter(typeof(NoneToDefaultConverter<string>))]
    public string category { get; set; }

    [JsonConverter(typeof(NoneToDefaultConverter<DateTime>))]
    public DateTime date { get; set; }

    [JsonConverter(typeof(NoneToDefaultConverter<decimal>))]
    public decimal amount { get; set; }
}

自定义默认值补充

如果不需要使用系统默认值(比如DateTime默认是0001/1/1),可以配合DefaultValue特性自定义默认值,只需要在全局设置中开启DefaultValueHandling.Populate即可:

public class Quote
{
    public string category { get; set; }

    [DefaultValue(typeof(DateTime), "2023-01-01 00:00:00")]
    public DateTime date { get; set; }

    [DefaultValue(typeof(decimal), "0.01")]
    public decimal amount { get; set; }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 09:57:00