2 回答
TA貢獻1934條經驗 獲得超2個贊
正如在解釋這個答案,以parse.com:SerializationException反序列化JSON與“__type”屬性的對象,你的問題是,"__type"是一個保留的屬性的DataContractJsonSerializer。它用于識別多態類型的派生類型。從文檔:
保留類型信息
為了保留類型標識,在將復雜類型序列化為 JSON 時,可以添加“類型提示”,并且反序列化器會識別該提示并采取適當的行動?!邦愋吞崾尽笔且粋€ JSON 鍵/值對,鍵名為“__type”(兩個下劃線后跟單詞“type”)。該值是“DataContractName:DataContractNamespace”形式的 JSON 字符串(第一個冒號之前的任何內容都是名稱)...
類型提示與 XML Schema Instance 標準定義的 xsi:type 屬性非常相似,并在序列化/反序列化 XML 時使用。
由于與類型提示的潛在沖突,禁止名為“__type”的數據成員。
因此,您無法手動將此屬性添加到您的類中并使其正確翻譯。
但是,您可以利用序列化程序對多態性的處理來"__type" 自動讀取和寫入,方法是定義一個Region類繼承自某個基類型的區域的類層次結構,例如RegionBase,由 引用Country.Parent:
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
public class Country
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string GeoType { get; set; }
[DataMember]
public RegionBase Parent { get; set; }
[DataMember]
public string RegionID { get; set; }
[DataMember]
public string CountryCode { get; set; }
[DataMember]
public string ISO { get; set; }
}
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
[KnownType(typeof(Region))]
public class RegionBase
{
}
[DataContract(
Name = "Region",
Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
public class Region : RegionBase
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string GeoType { get; set; }
[DataMember]
public string Code { get; set; }
}
然后反序列化為 a List<Country>,因為您的外部 JSON 容器是一個數組。
筆記:
類型提示的格式為"DataContractName:DataContractNamespace".
此外,如減少類型提示的大小中所述,類型提示中的前綴#是http://schemas.datacontract.org/2004/07/. 因此Region必須具有以下數據合約名稱:
[DataContract(
Name = "Region",
Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
我的答案中的類型層次結構足以反序列化示例 JSON,但它可能并不理想。例如,在實踐中,可能存在RegionBase與Region(例如ID)共享屬性的其他子類型,因此應該將這些屬性移至基類?;蛘呖赡苓€有其他可能的子類RegionBase未在您的問題中顯示,例如"SomeOtherKindOfRegion:#MEDEX.Library.Geo",需要將其添加到模型中。
由于這個 JSON 似乎來自 WCF 服務,因此希望它已經發布了它的Service Metadata。如果是這樣,它將允許您使用Visual Studio 中的添加服務引用自動生成客戶端。有關如何執行此操作的說明,請參閱如何:創建 Windows Communication Foundation 客戶端和如何:添加、更新或刪除服務引用。自動客戶端生成應該避免您遇到的困難。
有關這方面的示例,請參閱如何使用 DataContractSerializer 使用未命名的類型集合反序列化 JSON或如何使用 WSDL 文件創建 WCF 服務(不進行調用)。
數據契約序列化程序必須RegionBase通過已知類型機制獲知所有可能的多態子類型。
- 2 回答
- 0 關注
- 299 瀏覽
添加回答
舉報
