Reputation: 1403
After spending a day reading through posts here I still can't get this to work so hopefully this makes sense to someone here.
The web service returns this simple JSON
{"d":{"__type":"TestWebServices.Person","Name":"Bob","FavoriteColor":"Green","ID":0}}
Then I am using C# code to deserialize
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Person));
Person someone = (Person)jsonSerializer.ReadObject(responseStream);
When I use this model someone is created but all the properties are null
[DataContract]
public class Person {
[DataMember]
public string Name { get; set; }
[DataMember]
public string FavoriteColor { get; set; }
[DataMember]
public int ID { get; set; }
}
I tried being more literal and used this model
[DataContract]
public class Person {
[DataMember]
public PersonItem d { get; set; }
}
[DataContract]
public class PersonItem {
[DataMember]
public string __Type { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string FavoriteColor { get; set; }
[DataMember]
public int ID { get; set; }
}
And got this error, which I don't even know where to start with
Element ':d' contains data from a type that maps to the name ':GEMiniWebServices.Person'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'TestWebServices.Person' 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 DataContractSerializer.
Any thoughts? Thanks
Upvotes: 0
Views: 1991
Reputation: 13010
__Type should never be part of your object. It's a hint to the serializer. Also, the type hint that you have in your JSON object is bad. Stand-Alone JSON Serialization says:
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.
It works with the following if you rewrite the __type
declaration as Person:#TestWebServices
or eliminate it:
namespace TestWebServices
{
[KnownType(typeof(Person))]
[DataContract]
public class PersonWrapper
{
[DataMember]
public Person d { get; set; }
}
[DataContract]
public class Person
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string FavoriteColor { get; set; }
[DataMember]
public int ID { get; set; }
}
}
Upvotes: 1
Reputation: 871
Try adding (and I'm kind of taking a bit of a stab here so the exact namespace my be incorrect)
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/TestWebServices.Person")]
to your DataContractAttribute on Person.
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/TestWebServices.Person")]
public class Person {
[DataMember]
public PersonItem d { get; set; }
}
[DataContract]
public class PersonItem {
[DataMember]
public string __Type { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string FavoriteColor { get; set; }
[DataMember]
public int ID { get; set; }
}
Upvotes: 0