【问题标题】:How to deserialize JSON to only "built-in" types如何将 JSON 反序列化为仅“内置”类型
【发布时间】:2012-04-17 22:22:22
【问题描述】:

首先,我所以很抱歉提出另一个关于 JSON 反序列化的问题。但是,我还没有看到这个问题的答案。

我想将 JSON 反序列化为 T,其中 T 递归定义为:

  • Dictionary<string, T>
  • T[]
  • string
  • 原始类型
  • (object)T(盒装)

我知道那里的许多 JSON 库都允许指定反序列化类型,但是根据我的经验,一些自定义类型(JObjectJsonObject 等等)会出现在对象图中的某处(即返回类型似乎只适用于一定的深度)。这似乎很简单,因为类型与 JavaScript 的映射几乎是一对一的。

编辑

理想情况下,我希望 JSON 是“干净的”,即没有特殊字段(“__type”等)来帮助反序列化。它应该是来自 JavaScript 的直接映射:JObject -> IDictionary<string, T>JArray -> T[] 等等。

与此同时,我正在使用 FParsec 解析器和手动序列化器。它工作得很好,但我认为可能已经有一些东西了。

【问题讨论】:

  • 你试过 Newtonsoft.JSON 吗? (james.newtonking.com/pages/json-net.aspx) 这是 ravenDB 使用的,我在反序列化过程中没有遇到问题。
  • 是的,这就是我目前使用的,JObject 总是出现在深度嵌套的对象图中。
  • 能否提供一些示例代码和输入数据?

标签: c# json deserialization


【解决方案1】:

我不太确定您所说的“我想将 JSON 反序列化为 T,其中 T 被递归定义为”是什么意思,我的假设是您希望能够序列化和反序列化任何类型上面列出的任何组合。

我的经验表明,System.Runtime.Serialization.Json 特别是DataContractJsonSerializer 中提供的标准 DotNet 库对于您描述的工作来说已经足够了,并且将成功处理您提到的所有类型(没有元数据描述),而不是一个; T 的装箱对象。但是我的假设是,没有库能够在不提供元数据的情况下处理 T 的装箱对象(怎么可能?它对您的对象一无所知)

这是我用来在我的应用程序中提供序列化的一些代码

public class JSONSerializer<T>
{

    public static string Serialize(T obj)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
        using (MemoryStream stream = new MemoryStream()) {
            serializer.WriteObject(stream, obj);
            return Encoding.Default.GetString(stream.ToArray());
        }
    }

    public static T Deserialize(string json)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
        using (MemoryStream stream = new MemoryStream(Encoding.Default.GetBytes(json))) {
            return (T)serializer.ReadObject(stream);
        }
    }

}

PS:另请注意,DataContractSerializer 执行“纯”序列化和反序列化,而不使用任何代理类型对象(至少不在输出或输入中,可能在内部某处)。

【讨论】:

  • 我试图序列化一个实现 IDictionary&lt;string, object&gt; 的类,但它会出错。它必须检查运行时类型 (this.GetType()) 而不是 typeof(Dictionary&lt;string, object&gt;).IsAssignableFrom(type)
【解决方案2】:

您不能使用泛型。那是因为泛型必须在编译时剥离为一种类型。但是 JSON 对象或数组值应该是任何 JSON 类型,这是冲突的。

但如果你愿意,你可以使用object 然后施放它。 JSON 数组是 object[],JSON 对象是 Dictionary&lt;string,object&gt;。但这只是您提到的自定义类型的一种变体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-23
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 2012-10-01
    • 2017-12-19
    • 1970-01-01
    相关资源
    最近更新 更多