简体   繁体   中英

DataContractJsonSerializer Deserialization problem

I need to De-serialize Json array which is given bellow ....

[
    {
        "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"
    }
]

My object definition is:

[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; }
}

it is always getting error:

{"Element ':Parent' contains data from a type that maps to the name ' http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo:Region '. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver if you are using DataContractSerializer or add the type corresponding to 'Region' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to the serializer."}

Could you please suggest me any solution. I even don understand what this error means. Please suggest.

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

As explained in this answer to parse.com: SerializationException deserializing JSON objects with "__type" property , your problem is that the "__type" is a reserved property for DataContractJsonSerializer . It is used to identify derived types of polymorphic types. From the docs :

Preserving Type Information

To preserve type identity, when serializing complex types to JSON a "type hint" can be added, and the deserializer recognizes the hint and acts appropriately. The "type hint" is a JSON key/value pair with the key name of "__type" (two underscores followed by the word "type"). The value is a JSON string of the form "DataContractName:DataContractNamespace" (anything up to the first colon is the name)...

The type hint is very similar to the xsi:type attribute defined by the XML Schema Instance standard and used when serializing/deserializing XML.

Data members called "__type" are forbidden due to potential conflict with the type hint.

Thus you cannot manually add this property to your class and have it translate correctly.

You can, however, leverage the serializer's handling of polymorphism to read and write the "__type" automatically , by defining a class hierarchy of regions in which a Region class inherits from some base type, say RegionBase , which is referred to by 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; }
}

Then deserialize as a List<Country> , since your outer JSON container is an array.

Notes:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM