Serializing and Deserializing Type that Extends IE

2019-02-15 13:24发布

问题:

I am working with the Parse.com's API in C# and trying to serialize a class that extends ParseObject:

[ParseClassName("Battle")]
public class Battle : ParseObject
{
    [ParseFieldName("mapName")]
    public string MapName
    {
        get { return GetProperty<string>("MapName"); }
        set { SetProperty<string>(value, "MapName"); }
    }
}

Because ParseObject is

IEnumerable<KeyValuePair<string, object>>

The output is wrong:

[ { "Key": "mapName", "Value": "Worlds Collide" } ]

It should look like:

{ MapName: "Worlds Collide" }

I have tried to write a custom JsonConverter to handle it but I cannot for the life of me get it to deserialize properly.

public class ParseObjectJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        var can = objectType.IsSubclassOf(typeof(ParseObject));
        return can;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Load JObject from stream
        var jObject = JObject.Load(reader);

        var target = Activator.CreateInstance(objectType);

        var properties = objectType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
            .Where(prop => prop.GetSetMethod() != null).ToList();

        foreach (var p in jObject.Properties())
        {
            var targetProp = properties.FirstOrDefault(prop => prop.Name == p.Name);
            if(targetProp==null) continue;               

            targetProp.SetValue(target,  p.Value, null);
        }

        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var properties = value.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
            .Where(prop => prop.GetSetMethod() != null).Where(prop => prop.GetValue(value, null) != null).ToList();

        writer.WriteStartObject();

        foreach(var prop in properties)
        {
            writer.WritePropertyName(prop.Name);
            serializer.Serialize(writer, prop.GetValue(value, null));
        }

        writer.WriteEndObject();
    }    
}

Has anyone tried to serialise a ParseObject before or have any ideas how I should go about this?