【问题标题】:parse.com: SerializationException deserializing JSON objects with "__type" propertyparse.com:使用“__type”属性反序列化 JSON 对象的 SerializationException
【发布时间】:2015-11-16 23:25:36
【问题描述】:

我正在开发 Windows 10 UWP 应用,但似乎无法摆脱此错误: "在 mscorlib.ni.dll 中发生了 'System.Runtime.Serialization.SerializationException' 类型的异常,但未在用户代码中处理"

我正在使用 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"
    }
]
}

错误信息的详细信息如下: 附加信息:元素 ':image' 包含 ':File' 数据合约的数据。反序列化器不知道映射到该合约的任何类型。将与“文件”对应的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给 DataContractSerializer 的已知类型列表中。

【问题讨论】:

    标签: c# json parse-platform uwp datacontractjsonserializer


    【解决方案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" 值和属性数据的 JSON 数据(例如嵌入的 Base64 图像),您现在可以轻松修改数据模型以向 ImageBase 添加额外的子类。

    【讨论】:

    • 非常感谢,错误似乎已经解决,程序现在可以编译了。将 Result 类和 FileImage 类的成员绑定为 DataContext(特别是名称和 url)时,如何访问它们?
    • @JasonBourne - image 属性仍然存在并且可以公开访问。它将基础 ImageBase 属性转换为 FileImage 并返回它。所以你应该能够绑定到那个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多