Why am I using the KnownType attribute wrong?
I am trying to deserialize a json response from a google api, so i thought i would define a couple classes to help with it:
[DataContract]
public class DetectionResult:ResponseData
{
[DataMember(Name="language")]
public string Language
{ get; set; }
[DataMember(Name="isReliable")]
public bool IsReliable
{ get; set; }
[DataMember(Name="confidence")]
public double Confidence
{get;set;}
}
[DataContract]
public abstract class ResponseData
{
[DataMember(Name = "error")]
public TranslationError Error
{ get; set; }
}
[DataContract]
public class TranslationError
{
[DataMember(Name="code")]
public int Code
{ get; set; }
[DataMember(Name="message" )]
public int Message
{ get; set; }
}
[DataContract]
[KnownType(typeof(DetectionResult))]
public class RequestResult
{
[DataMember(Name="responseStatus")]
public int ResponseStatus
{ get; set; }
[D开发者_运维百科ataMember(Name="responseDetails")]
public string ResponseDetails
{ get; set; }
[DataMember(Name = "responseData")]
public ResponseData Response
{ get; set; }
}
The response I get after making the request is:
{"responseData": {"language":"en","isReliable":false,"confidence":0.114892714}, "responseDetails": null, "responseStatus": 200}
and use this code to deserialize it:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream stream = response.GetResponseStream())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(RequestResult));
RequestResult result = (RequestResult)serializer.ReadObject(stream);
stream.Close();
}
But am getting an exception stating "Cannot create an abstract class". Shouldnt it know about the DetectionResult class and properly deserialize it?
In your response data there is no way to infer a concrete type. The type to deserialize is not specified in the response.
From MSDN:
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). Using the earlier example, "Circle" can be serialized as follows.
http://msdn.microsoft.com/en-us/library/bb412170.aspx
See the section related to polymorphism.
Have you tried putting the KnownType attribute on ResponseData instead of RequestResult?
In that code sample you need [KnownType(typeof(DetectionResult))] to be an attribute of ResponseData rather than RequestResult.
I don't know if that's sufficient to resolve your problem
From my experience working with the DataContractSerializer and the XmlSerializer, when an unexpected type is met during serialization process, those serializers throw an exception; they don't simply do the best they can. Maybe the DataContractJsonSerializer does not support KnownTypes at all.
精彩评论