如何将 JSON 反序列化为仅“内置”类型

本文关键字:内置 类型 JSON 反序列化 | 更新日期: 2023-09-27 18:31:30

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

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

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

我知道许多 JSON 库都允许指定反序列化类型,但是,根据我的经验,一些自定义类型(JObjectJsonObject 等)显示在对象图中的某个地方(也就是说,返回类型似乎只应用于某个深度)。这似乎是直截了当的,因为这些类型几乎与JavaScript的一对一映射。

编辑

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

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

如何将 JSON 反序列化为仅“内置”类型

我不太确定你所说的"我想将 JSON 反序列化为 T,其中 T 被递归定义为"我假设你希望能够序列化和反序列化上面列出的任何类型以及任何组合。

我的经验表明,System.Runtime.Serialization.Json中可用的标准 DotNet 库DataContractJsonSerializer更适合您描述的工作,并且可以成功处理您提到的所有类型(没有元数据描述),而不是一个;一个 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 在不使用任何代理类型对象的情况下进行"纯"序列化和反序列化(至少不在输出或输入中,也许在内部的某个地方)。

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

但是如果你愿意,你可以使用object然后投射它。JSON 数组是object[]的,JSON 对象是Dictionary<string,object>的。但这只是您提到的自定义类型的变体。