JSON 即 JavaScript Object Natation,是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互。 .NET Framewok 3.5也提供了JSON对象序列化和反序列化的类,这就是System.Runtime.Serialization.Json 命名空间下的 DataContractJsonSerializer 类。利用这个类,可以实现JSON对象的序列化和反序列化。这种序列化最大的优点就是在前台的JavaScript代码不需要反序列化,就可以直接使用。 特别要注意的一点是System.Runtime.Serialization.Json,这个命名空间其实是在System.ServiceModel.Web.dll中,在引用的时候不要忘记。 还是以例子来进行辅助讲解: 首先写一个序列化器,作为序列化的工具 public static class Serializator { public static string EntityToJson<T>(T obj) where T: new() { var ds = new DataContractJsonSerializer(typeof (T)); using (var ms = new MemoryStream()) { ds.WriteObject(ms, obj); return Encoding.UTF8.GetString(ms.ToArray()); } } public static T JsonToEntity<T>(string jsonStr) { var ds = new DataContractJsonSerializer(typeof(T)); var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonStr)); var obj = (T)ds.ReadObject(ms); ms.Close(); return obj; } } 两个方法的作用分别是序列化和反序列化。 然后有两个实体类,分别定义了学生和家庭,在测试的过程中会使用到 [DataContract] public class Student { [DataMember] public string name { set; get; } [DataMember] public bool sex { set; get; } [DataMember] public int age { set; get; } [DataMember] public Home home { set; get; } } [DataContract] public class Home { [DataMember] public string Address { set;get;} } 对于DataContractAttribute类,MSDN的解释如下: 指定该类型要定义或实现一个数据协定,并可由序列化程序(如 DataContractSerializer)进行序列化。若要使其类型可序列化,类型作者必须为其类型定义数据协定。 但是我发现其实不写这个也可以正常编译执行。 进入正式的代码部分: 后台代码: protected void Page_Load(object sender, EventArgs e) { AjaxPro.Utility.RegisterTypeForAjax(typeof(JavaScript.Serializator.JsonSerialize)); } [AjaxPro.AjaxMethod] public string GetJson() { Student s1 = new Student() { name = "shark", sex = true, age = 25, home = new Home() { Address = "北京" } }; string result = Utility.Serializator.EntityToJson(s1); return result; } 后台代码很简单,Page_Load()中注册了AjaxPro,关于这个dll怎么使用,请看我前面的一篇博客。 GetJson()方法将Student的一个实例Json序列化之后抛到前台。在这个例子中,返回的result代码是: {"age":25,"home":{"Address":"北京"},"name":"shark","sex":true} 这就是Json序列化之后的字符串,具体的各种类型的字符串表示方法,文章介绍 JSON中写得很清楚了,我就不再多说。 让我们看看前台代码: function Start() { var items = JavaScript.Serializator.JsonSerialize.GetJson(); // 通过Ajax调用后台代码 var jstring = '(' + items.value + ')'; var j = eval(jstring); for(var p in j){ alert(p + ':' + j[p]); } } 前台代码也很简单,通过Ajax调用后台代码,这时候返回的是一个字符串,在字符串的两端加上括号(我也不知道为什么,反正不这样就出错,同时也想问问大家为什么和有没有更好的办法),然后执行这段,赋值给j,j此时是一个object类型的,也就是Student的一个实例了,可以获得每个属性并且显示出来,我们就可以操作它了。 前面的例子向我们展示了如何将一个类序列化之后抛到前台使用,下面更进一步,介绍如何将一个List<T>泛型类抛到前台并且使用。 后台代码中GetJson()函数修改如下: [AjaxPro.AjaxMethod] public string GetJson() { Student s1 = new Student() { name = "shark", sex = true, age = 25, home = new Home() { Address = "北京" } }; Student s2 = new Student() { name = "Lily", sex = false, age = 20, home = new Home() { Address = "上海" } }; Student s3 = new Student() { name = "Bill", sex = true, age = 25, home = new Home() { Address = "天津" } }; List<Student> ls = new List<Student>(); ls.Add(s1); ls.Add(s2); ls.Add(s3); string result = Utility.Serializator.EntityToJson(ls); return result; } 使用一个泛型类来存储多个学生的信息,序列化后抛到前台。此时的Json序列化后的字符串是: [{"age":25,"home":{"Address":"北京"},"name":"shark","sex":true},{"age":20,"home":{"Address":"上海"},"name":"Lily","sex":false},{"age":25,"home":{"Address":"天津"},"name":"Bill","sex":true}] 前台代码修改如下: function Start() { var items = JavaScript.Serializator.JsonSerialize.GetJson(); // 通过Ajax调用后台代码 var jstring = '(' + items.value + ')'; var j = eval(jstring); for (var p in j) { if (typeof (j[p]) == 'object') { for (var pp in j[p]) { alert(pp + ':' + j[p][pp]); } } } } j是一个object类型的,对应的是List<T>,它的属性中除了有3个Sudent对象之外还有List<T>中的方法:getArguments()和bind(),所以我们这里只列出j中类型是object的,也就是3个Student对象的信息。
|