parse.com: SerializationException 反序列化 JSON 个带有“__type”的对象 属性
parse.com: SerializationException deserializing JSON objects with "__type" property
我正在开发 Windows 10 UWP 应用程序,但似乎无法消除此错误:
"An exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.ni.dll but was not handled in user code"
我正在使用 Rest API 在 Parse 上从数据存储中检索值并实例化对象。
这是我的 Class 的样子
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”数据协定的数据。反序列化器不知道映射到该协定的任何类型。将对应于 'File' 的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给 DataContractSerializer 的已知类型列表中。
你的问题是你正在使用 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:
Preserving Type Information
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)...
The type hint is very similar to the xsi:type attribute defined by the XML Schema Instance standard and used when serializing/deserializing XML.
Data members called "__type" are forbidden due to potential conflict with the type hint.
因此您无法手动将此属性添加到您的class并使其正确翻译。
但是,您可以通过定义图像信息的 class 层次结构,利用序列化程序对多态性的处理来自动读取和写入 "__type"
其中您的 Image
类型是预期类型的子 class。为清楚起见,我们将其重命名为 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 数据,您现在可以轻松修改数据模型以添加额外的子 classes 到 ImageBase
.
我正在开发 Windows 10 UWP 应用程序,但似乎无法消除此错误: "An exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.ni.dll but was not handled in user code"
我正在使用 Rest API 在 Parse 上从数据存储中检索值并实例化对象。 这是我的 Class 的样子
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”数据协定的数据。反序列化器不知道映射到该协定的任何类型。将对应于 'File' 的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给 DataContractSerializer 的已知类型列表中。
你的问题是你正在使用 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:
Preserving Type Information
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)...
The type hint is very similar to the xsi:type attribute defined by the XML Schema Instance standard and used when serializing/deserializing XML.
Data members called "__type" are forbidden due to potential conflict with the type hint.
因此您无法手动将此属性添加到您的class并使其正确翻译。
但是,您可以通过定义图像信息的 class 层次结构,利用序列化程序对多态性的处理来自动读取和写入 "__type"
其中您的 Image
类型是预期类型的子 class。为清楚起见,我们将其重命名为 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 数据,您现在可以轻松修改数据模型以添加额外的子 classes 到 ImageBase
.