【问题标题】:DataContractJsonSerializer Deserialization problemDataContractJsonSerializer 反序列化问题
【发布时间】:2018-09-09 15:25:17
【问题描述】:

我需要对下面给出的 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; }
}

[DataContract]
public class Country
{
    [DataMember]
    public string ID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string GeoType { get; set; }
    [DataMember]
    public Parent1 Parent { get; set; }
    [DataMember]
    public string RegionID { get; set; }
    [DataMember]
    public string CountryCode { get; set; }
    [DataMember]
    public string ISO { get; set; }
}

总是报错:

{"Element ':Parent' 包含映射到名称 'http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo:Region' 的类型的数据。反序列化器不知道映射到此名称的任何类型。如果您正在使用 DataContractSerializer 或将对应于 'Region' 的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给序列化程序的已知类型列表中。"}

您能建议我任何解决方案吗?我什至不明白这个错误意味着什么。请提出建议。

【问题讨论】:

标签: c# asp.net asp.net-mvc-4 datacontractjsonserializer


【解决方案1】:

将 [KnownType(Region)] 添加到类 Parent1 属性

【讨论】:

    【解决方案2】:

    正如this answerparse.com: SerializationException deserializing JSON objects with "__type" property 中所述,您的问题是"__type"DataContractJsonSerializer保留属性。它用于识别多态类型的派生类型。来自docs

    保留类型信息

    为了保留类型标识,在将复杂类型序列化为 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; }
    }
    

    然后反序列化为List&lt;Country&gt;,因为您的外部 JSON 容器是一个数组。

    注意事项:

    【讨论】:

    • @SadaySarkar - 很高兴为您提供帮助。如果您的问题得到解答,请mark it as such
    猜你喜欢
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多