将不同格式的 JSON 对象反序列化为通用类

本文关键字:反序列化 对象 JSON 格式 | 更新日期: 2023-09-27 18:31:29

我有来自几个包含货币汇率的不同HTTP API的结果。结果非常相似,但不幸的是它们并不完全相同。

我想将它们反序列化为具有固定通用类型的对象。我想有一些比手动篡改字符串更好的方法。

有什么想法吗?

编辑:

比方说:

-从我得到API1的结果:

field_1, field_2, field_3

-根据我得到API2的结果:

field_1, field_2, field_007,

-从我得到API3的结果:

field_111, field_2, field_3,

我想反序列化结果的类如下所示:

class DeserializedJson
{
    public string field_1 { get; set; }
    public string field_2 { get; set; }
    public string field_3 { get; set; }
}

此示例中的重要内容:来自DeserializedJson对象的field_3只能显示为 field_3field_007 。这两个选项。

所以我只是想知道是否有条件反序列化属性或类似的东西?

将不同格式的 JSON 对象反序列化为通用类

注意:此答案是假设您将使用 Json.Net 编写的。 发布后,我意识到您从未在问题中特别提及您正在使用(或想要使用)的序列化程序。 我认为您仍然可以将此处介绍的相同技术与其他序列化程序一起使用,但您可能需要进行调整。扬子晚报.

好吧,只要您的映射不重叠,那么一个简单的解决方案就是在您的类中拥有私有 setter 供 Json.Net 使用,这将设置正确的公共属性。 这是有效的 Json.Net 因为 JSON 中没有的类成员。 下面是采用这种方法时修改后的类的外观:

class DeserializedJson
{
    public string field_1 { get; set; }
    public string field_2 { get; set; }
    public string field_3 { get; set; }
    [JsonProperty]
    private string field_007 
    {
        set { field_3 = value; }
    }
    [JsonProperty]
    private string field_111 
    {
        set { field_1 = value; }
    }
}

这里有一个演示来证明这是有效的:

class Program
{
    static void Main(string[] args)
    {
        DeserializeAndDump(1, @"{""field_1"":""a"",""field_2"":""b"",""field_3"":""c""}");
        DeserializeAndDump(2, @"{""field_1"":""d"",""field_2"":""e"",""field_007"":""f""}");
        DeserializeAndDump(3, @"{""field_111"":""g"",""field_2"":""h"",""field_3"":""i""}");
    }
    private static void DeserializeAndDump(int n, string json)
    {
        Console.WriteLine("--- API " + n + " ---");
        DeserializedJson obj = JsonConvert.DeserializeObject<DeserializedJson>(json);
        Console.WriteLine("field_1: " + obj.field_1);
        Console.WriteLine("field_2: " + obj.field_2);
        Console.WriteLine("field_3: " + obj.field_3);
        Console.WriteLine();
    }
}

输出:

--- API 1 ---
field_1: a
field_2: b
field_3: c
--- API 2 ---
field_1: d
field_2: e
field_3: f
--- API 3 ---
field_1: g
field_2: h
field_3: i

当然,例如,如果 JSON 中的field_007有时映射到类中的field_3,有时映射到类中的field_2,则此方法将不起作用。 如果是这种情况,则需要为每个不同的 API 方法创建一个单独的"反序列化 Json"类。 您可以使它们都继承自同一个基类,并在每个子类中使用上述技术在基类中设置正确的属性。 如下所示:

class DeserializedJson
{
    public string field_1 { get; set; }
    public string field_2 { get; set; }
    public string field_3 { get; set; }
}
class DeserializedJsonAPI1 : DeserializedJson
{
    [JsonProperty]
    private string field_007
    {
        set { field_2 = value; }
    }
}
class DeserializedJsonAPI2 : DeserializedJson
{
    [JsonProperty]
    private string field_007
    {
        set { field_3 = value; }
    }
}

演示:

class Program
{
    static void Main(string[] args)
    {
        DeserializeAndDump<DeserializedJsonAPI1>(1, @"{""field_1"":""q"",""field_007"":""r"",""field_3"":""s""}");
        DeserializeAndDump<DeserializedJsonAPI2>(2, @"{""field_1"":""x"",""field_2"":""y"",""field_007"":""z""}");
    }
    private static void DeserializeAndDump<T>(int n, string json) where T : DeserializedJson
    {
        Console.WriteLine("--- API " + n + " ---");
        DeserializedJson obj = JsonConvert.DeserializeObject<T>(json);
        Console.WriteLine("field_1: " + obj.field_1);
        Console.WriteLine("field_2: " + obj.field_2);
        Console.WriteLine("field_3: " + obj.field_3);
        Console.WriteLine();
    }
}

输出:

--- API 1 ---
field_1: q
field_2: r
field_3: s
--- API 2 ---
field_1: x
field_2: y
field_3: z

你在寻找这样的东西吗?

(YourClass)Newtonsoft.Json.JsonConvert.DeserializeObject(response, typeof(YourClass));

除非我误会了。如果你想要一个"通用"类型,请使用继承。