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 type hint is in the format "DataContractName:DataContractNamespace"
.
In addition, as explained in Reducing the Size of Type Hints , the prefix #
in the type hint is a shortcut for http://schemas.datacontract.org/2004/07/
. Thus Region
must have the following data contract name:
[DataContract( Name = "Region", Namespace = "http://schemas.datacontract.org/2004/07/MEDEX.Library.Geo")]
The type hierarchy in my answer is sufficient to deserialize the sample JSON, but it may not be ideal. For instance, in practice there may be other subtypes of RegionBase
that share properties with Region
(such as ID
), and so those properties should get moved to the base class. Or there may be other possible subclasses of RegionBase
not shown in your question, eg "SomeOtherKindOfRegion:#MEDEX.Library.Geo"
, which will need to be added to the model.
Since it appears this JSON comes from a WCF service, hopefully it has published its Service Metadata . If so, it will allow you to generate a client automatically using Add Service Reference in Visual Studio. For instructions on how to do this, see How to: Create a Windows Communication Foundation Client and How to: Add, Update, or Remove a Service Reference . Automatic client generation should avoid the difficulty you are having.
For examples of this see How to deserialize JSON with unnamed collection of types using DataContractSerializer or How to use a WSDL file to create a WCF service (not make a call) .
The data contract serializer must be informed of all possible polymorphic subtypes of RegionBase
via the Known Type mechanism .
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.