简体   繁体   中英

(De)Serialize DynamicObject with Jil?

I have a problem to (de)serialize DynamicObject with other json library that is not Newtownsoft.Json. (Jil, NetJSON, ServiceStack.Text...)

This is my expandable object class:

public class ExpandableObject : DynamicObject
{
    private readonly Dictionary<string, object> _fields = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
    [JsonIgnore]
    public Dictionary<string, object> Extra { get { return _fields; } }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        var membersNames = GetType().GetProperties().Where(propInfo => propInfo.CustomAttributes
            .All(ca => ca.AttributeType != typeof (JsonIgnoreAttribute)))
            .Select(propInfo => propInfo.Name);
        return Extra.Keys.Union(membersNames);
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _fields.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _fields[binder.Name] = value;
        return true;
    }
}

The problem with other libraries (like Jil) that the overridden methods don't invoked. With Newtonsoft.Json it works just great but the performance is bad.

For example - deserialize test of derived class:

public class Person : ExpandableObject
{
    public int Id { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var json = "{ \"Id\": 12 , \"SomeFiled\" : \"hello\" }";
        var person = Jil.JSON.Deserialize<Person>(json);            
    }
}

There is no exception .. It just ignored the "SomeFiled" field (should be in "Extra")

1.There is any solution?

2.And why Newtonsoft.Json able to perform the operation and JIL cannot? (or other fast library...). I understanded that the overridden methods should invoke by the DLR .. how can I make it work?

Thanks.

EDIT:

now I'm using DeserilizeDynamic instead of Deserialize(T). Now it works and my methods invokes by the DLR. the only problem for now is DeserilizeDynamic return 'dynamic' and doesn't have generic override (T). And because of that Web API cant resolve the type of the object on POST action for example. mabye in future...

If you look at the Common Pitfalls document in the wiki ( https://github.com/kevin-montrose/Jil/wiki/Common-Pitfalls ), you'll see the following:

If you have a class FooBase and a class Bar : FooBase and a call like JSON.Serialize(myBar), Jil will not serialize members inherited from FooBase by default. Note that in many cases the generic parameter can be inferred.

To fix this, pass an Options object with ShouldIncludeInherited set to true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM