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

ASP.NET中JSON.NET序列化反序列化自定义类型值Hashtable类型丢失问题

问题根因

Hashtable是非泛型集合,内部存储的元素默认类型为object,JSON.NET默认序列化配置不会写入自定义引用类型的类型元数据,反序列化时无法识别元素原本的User类型,会默认解析为JObject对象,导致类型丢失无法直接强转。

可用解决方案
  • 方案1:序列化时开启类型元数据写入(适配必须用Hashtable的场景)

    序列化和反序列化时同步配置TypeNameHandling.Auto,JSON.NET会在需要类型识别的对象节点上追加类型信息,反序列化时就能自动还原为原始User类型。

    注意:跨服务POST传输时建议同步将TypeNameAssemblyFormatHandling设为Simple,避免序列化结果带完整程序集强名称信息,导致接收端类型匹配失败,只要收发两端User类的命名空间、类名、结构一致即可正常解析。
    示例代码:

    // 初始化序列化配置
    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Auto,
        TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
    };
    
    // 原有序列化逻辑
    Hashtable ht = new Hashtable();
    User u = new User();
    u.name = "username";
    u.last = "userlastname";
    u.age = 30;
    ht.Add("user1", u);
    ht.Add("user2", u);
    ht.Add("user3", u);
    ht.Add("user4", u);
    string value = JsonConvert.SerializeObject(ht, settings);
    
    // 反序列化时传入相同配置即可
    Hashtable result = JsonConvert.DeserializeObject<Hashtable>(value, settings);
    // 取出的值可直接强转为User类型
    User user1 = (User)result["user1"];
    
  • 方案2:替换为泛型Dictionary(推荐最佳实践)

    Hashtable是C#泛型特性推出前的遗留非泛型类型,当键值对的值类型固定为User时,优先使用泛型Dictionary<string, User>替代,泛型集合本身携带明确的类型信息,不需要额外配置类型元数据即可完成正确的序列化、反序列化,性能和类型安全性都更高。
    示例代码:

    Dictionary<string, User> dict = new Dictionary<string, User>();
    User u = new User();
    u.name = "username";
    u.last = "userlastname";
    u.age = 30;
    dict.Add("user1", u);
    dict.Add("user2", u);
    dict.Add("user3", u);
    dict.Add("user4", u);
    
    // 序列化无需额外配置
    string value = JsonConvert.SerializeObject(dict);
    // 反序列化直接指定泛型类型,取出的值天然是User类型,无需强转
    Dictionary<string, User> result = JsonConvert.DeserializeObject<Dictionary<string, User>>(value);
    User user1 = result["user1"];
    
  • 方案3:反序列化后手动转换类型(适配无法修改序列化逻辑的场景)

    如果序列化端无法修改配置(比如接收第三方/前端传来的JSON数据),可以在反序列化得到Hashtable后,将内部存储的JObject对象手动转换为User类型。
    示例代码:

    Hashtable result = JsonConvert.DeserializeObject<Hashtable>(value);
    foreach (DictionaryEntry entry in result)
    {
        if (entry.Value is JObject jObj)
        {
            User user = jObj.ToObject<User>();
            // 对转换后的User对象做后续处理
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:48:17