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.