亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

DataContractJsonSerializer 反序列化問題

DataContractJsonSerializer 反序列化問題

C#
慕田峪9158850 2022-01-09 16:12:07
我需要反序列化下面給出的 Json 數組....[    {        "GeoType": 1,        "ID": "2650f7d2-7a5e-4b63-856c-07600fa2a854",        "Name": "Afghanistan",        "CapitalCity": null,        "CountryBoundaries": null,        "CountryCode": "AF",        "ISO": "AFG",        "Parent": {            "__type": "Region:#MEDEX.Library.Geo",            "GeoType": 0,            "ID": "6dc22edb-d711-4253-937f-242b0cd3c011",            "Name": "Asia",            "Code": "Asi"        },        "RegionID": "6dc22edb-d711-4253-937f-242b0cd3c011"    },    {        "GeoType": 1,        "ID": "3917c1c8-ee01-4e9b-8622-0fac9e9194ab",        "Name": "Albania",        "CapitalCity": null,        "CountryBoundaries": null,        "CountryCode": "AL",        "ISO": "ALB",        "Parent": {            "__type": "Region:#MEDEX.Library.Geo",            "GeoType": 0,            "ID": "b7ebd500-45e6-4a48-a2ef-f38fe99e7352",            "Name": "Europe",            "Code": "Eur"        },        "RegionID": "b7ebd500-45e6-4a48-a2ef-f38fe99e7352"    }]我的對象定義是:[DataContract]public class Parent1{    [DataMember]    public Dictionary<string, Type> __type { get; set; }    [DataMember]    public string ID { get; set; }    [DataMember]    public string Name { get; set; }    [DataMember]    public string GeoType { get; set; }    [DataMember]    public string Code { get; set; }}它總是出錯:{"元素 ':Parent' 包含映射到名稱 ' http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo:Region '的類型的數據。反序列化器不知道任何類型映射到此名稱。如果您使用 DataContractSerializer,請考慮使用 DataContractResolver,或者將與“Region”對應的類型添加到已知類型列表中 - 例如,通過使用 KnownTypeAttribute 屬性或將其添加到傳遞給的已知類型列表中序列化程序。"}你能建議我任何解決方案嗎?我什至不明白這個錯誤意味著什么。請建議。
查看完整描述

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通過已知類型機制獲知所有可能的多態子類型。


查看完整回答
反對 回復 2022-01-09
?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

將 [KnownType(Region)] 添加到類 Parent1 屬性


查看完整回答
反對 回復 2022-01-09
  • 2 回答
  • 0 關注
  • 299 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號