So I thought this would be possible and finally decided to give it a shot in 2010 Beta 2. It turns a bunch of JSON into an ExpandoObject using JSON.Net.
Needs cleaning up but not too bad.
[TestMethod]
public void DeserializeTestObjectToDynamic(){
TestObject testObject = new TestObject() {
FirstName = "Peter",
LastName = "Goodman",
DateOfBirth = new DateTime(1979, 2, 3),
Child = new TestChildObject {
Line1 = "child line 1",
Line2 = "child line 2",
Line3 = "child line 3",
City = "child city"
},
Children = new Collection<TestChildObject>() {
new TestChildObject() {
Line1 = "children 1 line 1",
Line2 = "children 1 line 2",
Line3 = "children 1 line 3",
City = "children 1 city"
},
new TestChildObject() {
Line1 = "children 2 line 1",
Line2 = "children 2 line 2",
Line3 = "children 2 line 3",
City = "children 2 city"
}
}
};
// Get our json string
string json = JsonConvert.SerializeObject(testObject);
// Create the json.Net Linq object for our json string
JObject jsonObject = JObject.Parse(json);
// eval into an expando
dynamic dynObject = ConvertJTokenToObject(jsonObject);
Assert.IsNotNull(dynObject);
Assert.IsNotInstanceOfType(dynObject, typeof(TestObject));
Assert.IsInstanceOfType(dynObject, typeof(ExpandoObject));
Assert.AreEqual(testObject.FirstName, dynObject.FirstName);
Assert.AreEqual(testObject.LastName, dynObject.LastName);
Assert.AreEqual(testObject.DateOfBirth, dynObject.DateOfBirth);
Assert.IsNotNull(dynObject.Child);
Assert.AreEqual(testObject.Child.Line1, dynObject.Child.Line1);
Assert.AreEqual(testObject.Child.Line2, dynObject.Child.Line2);
Assert.AreEqual(testObject.Child.Line3, dynObject.Child.Line3);
Assert.IsNotNull(dynObject.Children);
Assert.AreEqual(testObject.Children.Count, dynObject.Children.Length);
for (int i = 0; i < testObject.Children.Count; i++) {
Assert.AreEqual(testObject.Children[i].Line1, dynObject.Children[i].Line1);
Assert.AreEqual(testObject.Children[i].Line2, dynObject.Children[i].Line2);
Assert.AreEqual(testObject.Children[i].Line3, dynObject.Children[i].Line3);
}
}
public object ConvertJTokenToObject(JToken token) {
if (token is JValue) {
return ((JValue)token).Value;
}
if (token is JObject) {
ExpandoObject expando = new ExpandoObject();
(from childToken in ((JToken)token) where childToken is JProperty select childToken as JProperty).ToList().ForEach(property => {
((IDictionary<string, object>)expando).Add(property.Name, ConvertJTokenToObject(property.Value));
});
return expando;
}
if(token is JArray){
object[] array = new object[((JArray)token).Count];
int index = 0;
foreach (JToken arrayItem in ((JArray)token)) {
array[index] = ConvertJTokenToObject(arrayItem);
index++;
}
return array;
}
throw new ArgumentException(string.Format("Unknown token type '{0}'", token.GetType()), "token");
}