parse.com:SerializationException 使用“__type"反序列化 JSON 对象;财产 [英] parse.com: SerializationException deserializing JSON objects with "__type" property
问题描述
我正在开发 Windows 10 UWP 应用,但似乎无法摆脱此错误:在 mscorlib.ni.dll 中发生了‘System.Runtime.Serialization.SerializationException’类型的异常,但未在用户代码中处理"
I'm developing a Windows 10 UWP app and can't seem to get rid of this error: "An exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.ni.dll but was not handled in user code"
我正在使用 Rest API 从 Parse 上的数据存储检索值并实例化对象.这是我的班级的样子
I'm using the Rest API to retrieve values from a Data Store on Parse and instantiate objects. Here's what my Class looks like
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 输出的样子:
Here's what my JSON output looks like:
{
"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 的已知类型列表中.
The details of the error message are as follows: Additional information: Element ':image' contains data of the ':File' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'File' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.
推荐答案
您的问题是您正在使用 DataContractJsonSerializer
反序列化你的 JSON,"__type"
是一个保留属性 用于此序列化程序.它用于标识多态类型的派生类型.来自文档:
Your problem is that you are using the DataContractJsonSerializer
to deserialize your JSON, and "__type"
is a reserved property for this serializer. It is used to identify derived types of polymorphic types. From the docs:
保留类型信息
为了保留类型标识,在将复杂类型序列化为 JSON 时,可以添加类型提示",反序列化器会识别该提示并采取适当的行动.类型提示"是一个 JSON 键/值对,键名称为__type"(两个下划线后跟单词type").该值是DataContractName:DataContractNamespace"形式的 JSON 字符串(第一个冒号之前的任何内容都是名称)...
To preserve type identity, when serializing complex types to JSON a "type hint" can be added, and the deserializer recognizes the hint and acts appropriately. The "type hint" is a JSON key/value pair with the key name of "__type" (two underscores followed by the word "type"). The value is a JSON string of the form "DataContractName:DataContractNamespace" (anything up to the first colon is the name)...
类型提示与 XML 模式实例标准定义的 xsi:type 属性非常相似,在序列化/反序列化 XML 时使用.
The type hint is very similar to the xsi:type attribute defined by the XML Schema Instance standard and used when serializing/deserializing XML.
名为__type"的数据成员由于与类型提示的潜在冲突而被禁止.
因此您不能手动将此属性添加到您的类中并使其正确翻译.
Thus you cannot manually add this property to your class and have it translate correctly.
然而,您可以利用序列化程序对多态性的处理来"__type"
自动,通过定义图像信息的类层次结构,您的Image
类型是预期类型的子类.为了清楚起见,让我们将其重命名为 FileImage
:
You can, however, leverage the serializer's handling of polymorphism to read and write the "__type"
automatically, by defining a class hierarchy of image information in which your Image
type is a subclass of the expected type. Let's rename it to FileImage
for clarity:
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
.
If later you find that server is sending JSON data with additional "__type"
values and property data (e.g. an embedded Base64 image) you can now easily modify your data model to add additional subclasses to ImageBase
.
这篇关于parse.com:SerializationException 使用“__type"反序列化 JSON 对象;财产的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!