使用Json.Net序列化哈希表。

3

我有一个键类型为整数的哈希表,但是使用json.net进行反序列化时,键会以字符串形式返回,是否有办法在使用json.net进行序列化/反序列化时保持哈希表的键类型?该哈希表是'MyType'类型的属性。

var settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.Objects;
string json = JsonConvert.SerializeObject(o, Formatting.Indented, settings);

 mo = JsonConvert.DeserializeObject<MyType>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects });

public Hashtable jsonViews
{
    get { return mViews; }
    set { mViews = value; }
}

你是如何反序列化哈希表的?能展示一下代码吗? - toadflakz
我已经编辑了我的问题。 - Rafael
你可以把MyType类也发一下吗?至少公共属性... - toadflakz
代码不完整。MyType的定义在哪里?请发布生成的Json字符串,尽管我怀疑键已经被序列化为字符串,即用“”括起来。 - Panagiotis Kanavos
那就是访问哈希表的属性。 - Rafael
2
Json并不提供任何模式,因此它在保留类型方面并不好。键1"1"一样有效。除非在反序列化时指定所需的类型,否则Json.NET(或任何其他库)将选择最合适的类型 - 对于1是int类型,对于"1"是字符串类型。HashTable的键是一个未指定的对象。如果您想要一个特定的键,则应该使用类似Dictionary<>或MultiValueDictionary<>的类。 - Panagiotis Kanavos
2个回答

10
问题在于 System.Collections.Hashtable 没有强类型检查,它可以保存任何类型的对象,并且 JSON.NET 很可能会序列化您的哈希表内容的字符串表示形式。
在您花费太多时间调整JSON.NET的序列化器/反序列化器以弥补这一点之前,您可能需要考虑将您的 Hashtable 更换为 Dictionary < TKey,TValue >。它在性能方面几乎相同,但提供了强类型集合的优势和安全性。
强类型集合将解决您的Json.NET反序列化问题,因为Json.NET可以从字典中推断出类型。
使用 Dictionary < TKey,TValue > 而不是 Hashtable 在此处进行了讨论

0
这是我编写的一个通用静态扩展方法,可帮助我解决此问题。基本上,我希望即使数据以某种方式损坏,该代码也永远不会崩溃。
    public static T Read<T>(this Hashtable hash, string key)
    {
        if (!hash.ContainsKey(key))
            return default;
        if (hash[key] is T)
            return (T)hash[key];
        if (hash[key] is JToken token)
            return token.ToObject<T>();

        try
        {
            return (T)Convert.ChangeType(hash[key], typeof(T));
        }
        catch (InvalidCastException)
        {
            Debug.LogWarning($"{key} had the wrong type of {hash[key].GetType()}");
            return default;
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接