parse.com:SerializationException用" __ type"反序列化JSON对象属性

时间:2015-11-16 23:25:37

标签: c# json parse-platform uwp datacontractjsonserializer

我正在开发一个Windows 10 UWP应用程序,似乎无法摆脱这个错误: "类型' System.Runtime.Serialization.SerializationException'的例外情况发生在mscorlib.ni.dll但未在用户代码"

中处理

我使用Rest API从Parse上的数据存储中检索值并实例化对象。 这是我班级的样子

public class ImageTest
{
    public class Image
    {
        public string __type { get; set; }
        public string name { get; set; }
        public string url { get; set; }
    }

    public class Result
    {
        public string createdAt { get; set; }
        public Image image { get; set; }
        public string name { get; set; }
        public string objectId { get; set; }
        public string updatedAt { get; set; }
    }

    public class RootObject
    {
        public List<Result> results { get; set; }
    }
}

这是我的JSON输出:

{
"results": [
    {
        "createdAt": "2015-11-16T02:04:17.403Z",
        "image": {
            "__type": "File",
            "name": "stark.jpg",
            "url": "http://xyz.parse.com/stark.jpg"
        },
        "name": "Stark",
        "objectId": "2ypGrvkvg0",
        "updatedAt": "2015-11-16T02:04:23.121Z"
    },
    {
        "createdAt": "2015-11-16T02:04:31.409Z",
        "image": {
            "__type": "File",
            "name": "targaryen.jpg",
            "url": "http://xyz.parse.com/targaryen.jpg"
        },
        "name": "Targaryen",
        "objectId": "otgO3scX3k",
        "updatedAt": "2015-11-16T02:04:40.094Z"
    }
]
}

错误消息的详细信息如下: 附加信息:元素&#39;:图像&#39;包含&#39;:文件&#39;的数据数据合同。反序列化器不知道映射到此合同的任何类型。添加与&#39;文件&#39;对应的类型到已知类型列表 - 例如,通过使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表。

1 个答案:

答案 0 :(得分:1)

您的问题是您使用DataContractJsonSerializer反序列化JSON,"__type"是此序列化程序的保留属性。它用于识别多态类型的派生类型。来自docs

  

保留类型信息

     

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

     

类型提示非常类似于XML Schema Instance标准定义的xsi:type属性,在序列化/反序列化XML时使用。

     

由于与类型提示的潜在冲突,禁止使用名为“__type”的数据成员。

因此,您无法手动将此属性添加到您的班级并让其正确翻译。

然而,您可以利用序列化程序处理多态来自动读取和写入"__type" ,方法是定义Image类型的图像信息的类层次结构是期望类型的子类。为清楚起见,我们将其重命名为FileImage

public class ImageTest
{
    [DataContract(Namespace = "")]
    [KnownType(typeof(FileImage))]
    public abstract class ImageBase
    {
    }

    [DataContract(Name = "File", Namespace = "")]
    public sealed class FileImage : ImageBase
    {
        [DataMember(Name = "name")]
        public string name { get; set; }
        [DataMember(Name = "url")]
        public string url { get; set; }
    }

    [DataContract(Namespace = "")]
    public class Result
    {
        [DataMember]
        public string createdAt { get; set; }

        [IgnoreDataMember]
        public FileImage image { get { return imageBase as FileImage; } set { imageBase = value; } }

        [DataMember(Name = "image")] // Need not be public if DataMember is applied.
        ImageBase imageBase { get; set; }

        [DataMember]
        public string name { get; set; }

        [DataMember]
        public string objectId { get; set; }

        [DataMember]
        public string updatedAt { get; set; }
    }

    public class RootObject
    {
        public List<Result> results { get; set; }
    }
}

现在一切都应该有效。

如果稍后您发现服务器正在发送带有其他"__type"值和属性数据(例如嵌入式Base64图像)的JSON数据,您现在可以轻松修改数据模型以向ImageBase添加其他子类。