Serializing System.Dynamic.dynamicobject

Dec 10, 2013 at 6:48 PM
Let's say I have a custom DynamicObject that has a set of custom properties and an internal property bad like the following:
 public class LogItem: DynamicObject
    {
        public virtual string ID { get; set; }        
        public virtual string Message { get; set; }        

        protected IDictionary<string, object> LogData { get; set; }

        public LogItem()
        {
            LogData = new Dictionary<string, object>();
        }

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

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            return LogData.TryGetValue(binder.Name, out result);
        }
    }
What's the best approach for me to serialize instances of this type. The following code returns nothing
            dynamic exp = new LogItem();
            exp.Message = "Test";
            exp.Payload = new { ID = "101", User = "me"};
            Console.WriteLine( JsonConvert.SerializeObject(exp));  //returns  "{}"
ExpandoObject object serialize just fine, but that type is sealed in the BCL
Dec 26, 2013 at 10:38 PM
ExpandoObject implements IDictionary<string,object>, I suspect that is why it works
Also look into DynamicMetaObject.GetDynamicMemberNames(), another method on DynamicObject
and finally, you might need to mark the class with the JsonObject attribute and your props with [JsonProperty].
 [JsonObject(MemberSerialization.OptIn)]
 public class LogItem: DynamicObject
    {
        [JsonProperty]
        public virtual string ID { get; set; }      
        [JsonProperty]
        public virtual string Message { get; set; }        

        protected IDictionary<string, object> LogData { get; set; }

        public LogItem()
        {
            LogData = new Dictionary<string, object>();
        }

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

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

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return LogData.Keys;
        }
    }
Jan 17, 2014 at 9:38 PM
This works. Thanks!