为什么我使用KnownType属性错误?

我试图从谷歌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类并正确反序列化吗?

在您的响应数据中,无法推断出具体类型。 未在响应中指定要反序列化的类型。

来自MSDN:

要保留类型标识,在将复杂类型序列化为JSON时,可以添加“类型提示”,并且反序列化程序可以识别提示并采取相应的操作。 “类型提示”是一个JSON键/值对,键名为“__type”(两个下划线后跟单词“type”)。 该值是“DataContractName:DataContractNamespace”forms的JSON字符串(第一个冒号的任何内容都是名称)。 使用前面的示例,“Circle”可以按如下方式序列化。

http://msdn.microsoft.com/en-us/library/bb412170.aspx

请参阅与多态性相关的部分。

您是否尝试将KnownType属性放在ResponseData而不是RequestResult上?

在该代码示例中,您需要[KnownType(typeof(DetectionResult))]作为ResponseData的属性而不是RequestResult。

我不知道这是否足以解决您的问题

根据我使用DataContractSerializer和XmlSerializer的经验,当在序列化过程中遇到意外类型时,这些序列化程序会抛出exception; 他们不是简单地尽力而为。 也许DataContractJsonSerializer根本不支持KnownTypes。