【问题标题】:Why am I using the KnownType attribute wrong?为什么我错误地使用 KnownType 属性?
【发布时间】:2009-11-18 21:23:18
【问题描述】:

我正在尝试反序列化来自 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 类并正确反序列化它吗?

【问题讨论】:

    标签: c# wcf serialization datacontract


    【解决方案1】:

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

    来自 MSDN:

    为了保留类型标识,在将复杂类型序列化为 JSON 时, 可以添加“类型提示”,反序列化器识别提示并 采取适当的行动。 “类型提示”是一个 JSON 键/值对,带有 “__type”的键名(两个下划线后跟单词“type”)。 该值是一个 JSON 字符串,格式为 “DataContractName:DataContractNamespace”(直到第一个 冒号是名称)。使用前面的例子,“圆”可以是 序列化如下。

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

    参见与多态性相关的部分。

    【讨论】:

    • 很棒的链接!非常感谢您找到它。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2011-07-20
          • 2011-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-19
          • 1970-01-01
          相关资源
          最近更新 更多