簡體   English   中英

JSON Newtonsoft C#反序列化不同類型的對象的列表

[英]JSON Newtonsoft C# Deserialize List of Objects of Different Types

我需要為現有報告接口實現遠程連接,這需要對數據類進行序列化和反序列化。 這是類和接口的簡化版本:

    public interface IBase
    {
        string Name { get; }
    }

    public interface IDerived1
    {
        int Value { get; }
    }

    public interface IDerived2
    {
        bool Value { get; }
    }

    public class Base : IBase
    {
        public string Name { get; protected set; }
    }

    public class Derived1 : Base, IDerived1
    {
        public int Value { get; protected set; }
    }

    public class Derived2 : Base, IDerived2
    {
        public bool Value { get; protected set; }
    }

作為輸入參數,我得到

IEnumerable<IBase> reportingData

因此,此集合可以包含任意數量的'Derived1'和'Derived2'實例及其組合。 然后,我像這樣序列化集合:

string serialisedReportingData = JsonConvert.SerializeObject( reportingData );

例如,這給了我:

[{“ Value”:11,“ Name”:“產品編號”},{“ Value”:false,“ Name”:“已啟用輸出1”}]

顯然,僅憑此數據,就不可能進行反序列化,因為單個集合條目的類型不在JSON中。 例如,我可以將類型作為JSON的一部分,或提供反序列化期間使用的其他類型集合。

我以前使用過CustomCreationConverter重載來處理

JsonConvert.DeserializeObject<IEnumerable<Ixxx>>( ... );

類型的方案,但這僅適用於IEnumerable內部的單個接口類型。 在上面的示例中,我有兩個:IDerived1和IDerived2。

我的問題:

a)我不確定如何編寫處理多個接口類型的CustomCreationConverter,並且我不知道如何將類型添加到其中。

b)我希望您提出有關如何實施解決方案的建議,該解決方案將為我提供與我作為輸入收到的“ IEnumerableReportingData”相同的反序列化輸出。

在可能的情況下,我將非常感謝一個有效的代碼示例。

預先感謝,克里斯汀

更新:(受dbc的評論啟發)

使用類型名稱反序列化時,應使用SerializationBinder 請參閱此處的KnownTypesBinder (需要Newtonsoft.Json版本大於10的版本)

首先,如果要設置屬性,則必須將其設置為public 然后,您可以使用JsonSerializerSettings進行序列化/反序列化。

List<IBase> loList = new List<IBase>();
loList.Add(new Base() { Name = "Base" });
loList.Add(new Derived1() { Name = "Derived1", Value = 3 });
loList.Add(new Derived2() { Name = "Derived2", Value = true });

KnownTypesBinder loKnownTypesBinder = new KnownTypesBinder()
{
    KnownTypes = new List<Type> { typeof(Base), typeof(Derived1), typeof(Derived2) }
};

IEnumerable<IBase> reportingData = loList.AsEnumerable();
JsonSerializerSettings loJsonSerializerSettings = new JsonSerializerSettings()
{
    TypeNameHandling = TypeNameHandling.Objects,
    SerializationBinder = loKnownTypesBinder
};

string lsOut = JsonConvert.SerializeObject(reportingData, loJsonSerializerSettings);
reportingData = JsonConvert.DeserializeObject<IEnumerable<IBase>>(lsOut, loJsonSerializerSettings);

如果像這樣使用JsonSerializerSettings ,則類型信息將包含在json字符串中。

[{
        "$type": "Base",
        "Name": "Base"
    }, {
        "$type": "Derived1",
        "Value": 3,
        "Name": "Derived1"
    }, {
        "$type": "Derived2",
        "Value": true,
        "Name": "Derived2"
    }
]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM