parse.com: SerializationException deserializing JSON objects with “__type” property

帅比萌擦擦* 提交于 2019-12-02 03:03:56

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:

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.

Thus you cannot manually add this property to your class and have it translate correctly.

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; }
    }
}

Now everything should work.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!