![](/img/trans.png)
[英]How to deserialize an item into different types? (Newtonsoft, C#, .NET)
[英]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.