Using dynamic
It is possible to extend a DynamicObject
to get the values as follows:
public class DynamicJsonObject : DynamicObject
{
private IDictionary<string, object> Dictionary { get; set; }
public DynamicJsonObject(IDictionary<string, object> dictionary)
{
this.Dictionary = dictionary;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this.Dictionary[binder.Name];
if (result is IDictionary<string, object>)
{
result = new DynamicJsonObject(result as IDictionary<string, object>);
}
else if (result is ArrayList && (result as ArrayList) is IDictionary<string, object>)
{
result = new List<DynamicJsonObject>((result as ArrayList).ToArray().Select(x => new DynamicJsonObject(x as IDictionary<string, object>)));
}
else if (result is ArrayList)
{
result = new List<object>((result as ArrayList).ToArray());
}
// nunca lança exceção se não encontrar o valor
return true;
// this.Dictionary.ContainsKey(binder.Name);
}
}
And extend JavaScriptConverter
to get values
public class DynamicJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
if (type == typeof(object))
{
return new DynamicJsonObject(dictionary);
}
return null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(object) })); }
}
}
And to use
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });
dynamic json = jss.Deserialize(jsonString, typeof(object));
This way you can dynamically access object values.
json.name
json.id
// ...
You could modify the method TrySetMember
of DynamicJsonObject
so that you could modify the values of the object. It is shown as read only.