我正在尝试从google api反序列化json响应,所以我想我会定义几个类来帮助它:
[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; }
[DataMember(Name="responseDetails")]
public string ResponseDetails
{ get; set; }
[DataMember(Name = "responseData")]
public ResponseData Response
{ get; set; }
}
发出请求后我得到的回复是:
{"responseData": {"language":"en","isReliable":false,"confidence":0.114892714}, "responseDetails": null, "responseStatus": 200}
并使用此代码对其进行反序列化:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream stream = response.GetResponseStream())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(RequestResult));
RequestResult result = (RequestResult)serializer.ReadObject(stream);
stream.Close();
}
但是我得到一个异常,说明“无法创建一个抽象类”。难道它不知道DetectionResult类并正确反序列化吗?
答案 0 :(得分:11)
在您的回复数据中,无法推断具体类型。未在响应中指定要反序列化的类型。
来自MSDN:
在将复杂类型序列化为JSON时保留类型标识a 可以添加“type hint”,并且反序列化器识别提示和 行为恰当。 “类型提示”是一个JSON键/值对 键名“__type”(两个下划线后跟单词“type”)。 该值是表单的JSON字符串 “DataContractName:DataContractNamespace”(任何东西都是第一个 冒号是名字)。使用前面的例子,“Circle”可以 序列化如下。
http://msdn.microsoft.com/en-us/library/bb412170.aspx
请参阅与多态性相关的部分。
答案 1 :(得分:1)
您是否尝试将KnownType属性放在ResponseData上而不是RequestResult?
答案 2 :(得分:1)
在该代码示例中,您需要[KnownType(typeof(DetectionResult))]作为ResponseData的属性而不是RequestResult。
我不知道这是否足以解决您的问题
答案 3 :(得分:0)
根据我使用DataContractSerializer和XmlSerializer的经验,当在序列化过程中遇到意外类型时,这些序列化程序会抛出异常;他们不是简单地尽力而为。也许DataContractJsonSerializer根本不支持KnownTypes。