An alternative deserialisation approach is suggested here. I modified the code slightly to fix a bug and suit my coding style. All you need is this:

2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Collections.ObjectModel;
5 using System.Dynamic;
6 using System.Linq;
7 using System.Text;
8 using System.Web.Script.Serialization;
9
10 private sealed class DynamicJsonConverter : JavaScriptConverter
11 {
12 public override object Deserialize(IDictionary< string, object> dictionary, Type type, JavaScriptSerializer serializer)
13 {
14 if (dictionary == null)
15 throw new ArgumentNullException( " dictionary ");
16
17 return type == typeof( object) ? new DynamicJsonObject(dictionary) : null;
18 }
19
20 public override IDictionary< string, object> Serialize( object obj, JavaScriptSerializer serializer)
21 {
22 throw new NotImplementedException();
23 }
24
25 public override IEnumerable<Type> SupportedTypes
26 {
27 get { return new ReadOnlyCollection<Type>( new List<Type>( new[] { typeof( object) })); }
28 }
29
30 #region Nested type: DynamicJsonObject
31
32 private sealed class DynamicJsonObject : DynamicObject
33 {
34 private readonly IDictionary< string, object> _dictionary;
35
36 public DynamicJsonObject(IDictionary< string, object> dictionary)
37 {
38 if (dictionary == null)
39 throw new ArgumentNullException( " dictionary ");
40 _dictionary = dictionary;
41 }
42
43 public override string ToString()
44 {
45 var sb = new StringBuilder( " { ");
46 ToString(sb);
47 return sb.ToString();
48 }
49
50 private void ToString(StringBuilder sb)
51 {
52 var firstInDictionary = true;
53 foreach ( var pair in _dictionary)
54 {
55 if (!firstInDictionary)
56 sb.Append( " , ");
57 firstInDictionary = false;
58 var value = pair.Value;
59 var name = pair.Key;
60 if (value is string)
61 {
62 sb.AppendFormat( " {0}:\"{1}\" ", name, value);
63 }
64 else if (value is IDictionary< string, object>)
65 {
66 new DynamicJsonObject((IDictionary< string, object>)value).ToString(sb);
67 }
68 else if (value is ArrayList)
69 {
70 sb.Append(name + " :[ ");
71 var firstInArray = true;
72 foreach ( var arrayValue in (ArrayList)value)
73 {
74 if (!firstInArray)
75 sb.Append( " , ");
76 firstInArray = false;
77 if (arrayValue is IDictionary< string, object>)
78 new DynamicJsonObject((IDictionary< string, object>)arrayValue).ToString(sb);
79 else if (arrayValue is string)
80 sb.AppendFormat( " \"{0}\" ", arrayValue);
81 else
82 sb.AppendFormat( " {0} ", arrayValue);
83
84 }
85 sb.Append( " ] ");
86 }
87 else
88 {
89 sb.AppendFormat( " {0}:{1} ", name, value);
90 }
91 }
92 sb.Append( " } ");
93 }
94
95 public override bool TryGetMember(GetMemberBinder binder, out object result)
96 {
97 if (!_dictionary.TryGetValue(binder.Name, out result))
98 {
99 // return null to avoid exception. caller can check for null this way...
100 result = null;
101 return true;
102 }
103
104 var dictionary = result as IDictionary< string, object>;
105 if (dictionary != null)
106 {
107 result = new DynamicJsonObject(dictionary);
108 return true;
109 }
110
111 var arrayList = result as ArrayList;
112 if (arrayList != null && arrayList.Count > 0)
113 {
114 if (arrayList[ 0] is IDictionary< string, object>)
115 result = new List< object>(arrayList.Cast<IDictionary< string, object>>().Select(x => new DynamicJsonObject(x)));
116 else
117 result = new List< object>(arrayList.Cast< object>());
118 }
119
120 return true;
121 }
122 }
123
124 #endregion
125 }
You can use it like this:

2
3 var serializer = new JavaScriptSerializer();
4 serializer.RegisterConverters( new[] { new DynamicJsonConverter() });
5
6 dynamic obj = serializer.Deserialize(json, typeof( object));
So, given a JSON string:

2 " Items ":[
3 { " Name ": " Apple ", " Price ": 12.3 },
4 { " Name ": " Grape ", " Price ": 3.21 }
5 ],
6 " Date ": " 21/11/2010 "
7 }
The following code will work at runtime:

2
3 data.Date; // "21/11/2010"
4 data.Items.Count; // 2
5 data.Items[ 0].Name; // "Apple"
6 data.Items[ 0].Price; // 12.3 (as a decimal)
7 data.Items[ 1].Name; // "Grape"
8 data.Items[ 1].Price; // 3.21 (as a decimal)
I'm interested in any discussion about this approach.
EDIT
I updated the code to fix a small bug (with lists of complex types) and to include a ToString
method that outputs the JSON string, which I found useful for debugging. You can drop the two methods out if you don't want them as they aren't required for deserialisation.
It's pretty simple using Newtonsoft.Json:

2 dynamic stuff = jsonSerializer.Deserialize( new JsonTextReader( new StringReader( " { 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 } ")));
3
4 var name = stuff.Name;
5 var address = stuff.Address.City;
.Net 4.0 has a built-in library to do this:

2 JavaScriptSerializer jss = new JavaScriptSerializer();
3 var d=jss.Deserialize<dynamic>(str);
This is the simplest way You can use it like this:

1 (new System.Collections.Generic.Mscorlib_DictionaryDebugView<string,object>(((System.Collections.Generic.Dictionary<string,object>)(obj[0])))).Items[1]
refer to:
http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object
這有一篇介紹動態解析原理的文章:http://www.codeproject.com/Articles/349646/Dynamic-JSON-parser