我们在.net中处理json数据时,经常需要定义相应的类。比如json数据:{ "name" : "hello", "age" : 18 },则需要定义相应的类,包含属性 name、age。
如果不想定义那些烦人的类怎么办?这就用到了.net 4.0的动态类型。
1、自定义JavaScriptConverter

1 /// <summary> 2 /// json转dynamic的转换器 3 /// </summary> 4 public class JsonDynamicConverter : System.Web.Script.Serialization.JavaScriptConverter 5 { 6 /// <summary> 7 /// 自动定义反序列化 8 /// </summary> 9 /// <param name="dictionary"></param> 10 /// <param name="type"></param> 11 /// <param name="serializer"></param> 12 /// <returns></returns> 13 public override object Deserialize(IDictionary<string, object> dictionary, Type type, System.Web.Script.Serialization.JavaScriptSerializer serializer) 14 { 15 if (dictionary == null) 16 throw new ArgumentNullException("dictionary"); 17 18 if (type == typeof(object)) 19 { 20 return new JsonDynamicObject(dictionary); 21 } 22 23 return null; 24 } 25 26 /// <summary> 27 /// 序列化 28 /// </summary> 29 /// <param name="obj"></param> 30 /// <param name="serializer"></param> 31 /// <returns></returns> 32 public override IDictionary<string, object> Serialize(object obj, System.Web.Script.Serialization.JavaScriptSerializer serializer) 33 { 34 throw new NotImplementedException(); 35 } 36 37 /// <summary> 38 /// 支持的类型 39 /// </summary> 40 public override IEnumerable<Type> SupportedTypes 41 { 42 get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(object) })); } 43 } 44 }
2、定义JsonDynamicObject

1 /// <summary> 2 /// 代表json的动态对象 3 /// </summary> 4 public class JsonDynamicObject : System.Dynamic.DynamicObject 5 { 6 private IDictionary<string, object> dictionary { get; set; } 7 8 /// <summary> 9 /// 构造动态json对象 10 /// </summary> 11 /// <param name="dictionary"></param> 12 public JsonDynamicObject(IDictionary<string, object> dictionary) 13 { 14 this.dictionary = dictionary; 15 } 16 17 /// <summary> 18 /// 获取成员 19 /// </summary> 20 /// <param name="binder"></param> 21 /// <param name="result"></param> 22 /// <returns></returns> 23 public override bool TryGetMember(GetMemberBinder binder, out object result) 24 { 25 if (this.dictionary.ContainsKey(binder.Name) == false) 26 { 27 result = null; 28 return true; 29 } 30 31 result = this.dictionary[binder.Name]; 32 33 if (result is IDictionary<string, object>) 34 { 35 result = new JsonDynamicObject(result as IDictionary<string, object>); 36 } 37 else if (result is ArrayList && (result as ArrayList).Count > 0 && (result as ArrayList)[0] is IDictionary<string, object>) 38 { 39 result = new List<dynamic>((result as ArrayList).ToArray().Select(x => new JsonDynamicObject(x as IDictionary<string, object>))); 40 } 41 else if (result is ArrayList) 42 { 43 result = new List<dynamic>((result as ArrayList).ToArray()); 44 } 45 46 this.dictionary[binder.Name] = result; 47 48 return this.dictionary.ContainsKey(binder.Name); 49 } 50 51 /// <summary> 52 /// 转换json字符串到dynamic 53 /// </summary> 54 /// <param name="json"></param> 55 /// <returns></returns> 56 public static dynamic FromJson(string json) 57 { 58 var jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 59 jsSerializer.RegisterConverters(new[] { new JsonDynamicConverter() }); 60 return jsSerializer.Deserialize(json, typeof(object)); 61 } 62 }
3、具体用法
1 var json = "{ \"name\" : \"hello\", \"age\" : 18 }"; 2 var person = JsonDynamicObject.FromJson(json); 3 Console.WriteLine("name:{0},age:{1}", person.name, person.age);
是不是再也不用定义那些烦人的类了~