我正在开发一个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的已知类型列表。
答案 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
添加其他子类。