Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't Serialize a class extending DynamicObject into JSON string.

I have class foo which is extending DynamicObject class. This class also contains a property of Dictionary type.

When I am trying to serialize it using Newton.Soft Json converter. I am getting "{}" as blank object.

Following is my code:

public class Foo: DynamicObject
       {
           /// <summary>
           ///     Gets or sets the properties.
           /// </summary>
           /// <value>The properties.</value>
           public Dictionary<string, object> Properties { get; set; } = new Dictionary<string, object>();

           /// <summary>
           ///     Gets the count.
           /// </summary>
           /// <value>The count.</value>
           public int Count => Properties.Keys.Count;

       }

Now I mentioned, while serializing it I am getting blank object. Follwing is the code for serialization:

public static void Main()
{
  Foo foo= new Foo();
           foo.Properties = new Dictionary<string, object>()
           {
               {"SomeId", 123},
               {"DataType","UnKnonw"},
               {"SomeOtherId", 456},
               {"EmpName", "Pranay Deep"},
              {"EmpId", "789"},
              {"RandomProperty", "576Wow_Omg"}
          };

           //Now serializing..
           string jsonFoo = JsonConvert.SerializeObject(foo);
           //Here jsonFoo = "{}".. why?
           Foo foo2= JsonConvert.DeserializeObject<Foo>(jsonFoo);
}

Please let me know if I am missing somthing?

like image 752
Pranay Deep Avatar asked Apr 06 '18 08:04

Pranay Deep


1 Answers

Dynamic objects are treated in a special way by JSON.NET. DynamicObject has GetDynamicMemberNames method which is expected to return names of properties for that object. JSON.NET will use this method and serialize properties with names returned by it. Since you didn't override it (or if you did - you don't return name of Properties and Count properties from it) - they are not serialized.

You can either make that method return what you need or, better, just mark both Properties and Count with JsonProperty - then they will be serialized anyway:

public class Foo : DynamicObject
{
    [JsonProperty]
    public Dictionary<string, object> Properties { get; set; } = new Dictionary<string, object>();

    [JsonProperty]
    public int Count => Properties.Keys.Count;
}

// also works, NOT recommended
public class Foo : DynamicObject
{        
    public Dictionary<string, object> Properties { get; set; } = new Dictionary<string, object>();

    public int Count => Properties.Keys.Count;

    public override IEnumerable<string> GetDynamicMemberNames() {
        return base.GetDynamicMemberNames().Concat(new[] {nameof(Properties), nameof(Count)});
    }
}
like image 104
Evk Avatar answered Nov 14 '22 21:11

Evk