1

我正在开发 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 的已知类型列表中。

4

1 回答 1

1

您的问题是您正在使用DataContractJsonSerializer反序列化您的 JSON,并且"__type"是此序列化程序的保留属性。它用于识别多态类型的派生类型。从文档

保留类型信息

为了保留类型标识,在将复杂类型序列化为 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.

于 2015-11-17T00:12:50.613 回答