几年前还是XML序列化大行其道的时代,几乎所有的书讲的都是如何使用XML,随着RIA技术(包括AJAX和Silverlight等)的出现,我们更需要简单、灵活的序列化方式,这也是JSON回归的原因。ASP.NET Web应用程序所展现数据量越来越大,无论是数据库访问还是网络数据流量都成为了其瓶颈,在减少网页回发(IE经典白画面)的同时,使用AJAX进行异步请求的数据量也是我们考虑的重点。
看一下现在ASP.NET 3.5中支持的JSON序列化工具,包括:
JavascriptSerializer
DataContractJsonSerializer
前者默认(除适用JSON序列化转换类的情况)序列化所有字段,在大多数情况下会引起错误(毕竟我们有无法序列化的类型),而且大部分类都有不需要序列化的属性,而我们也不能为每一个类都写一个序列化转换类吧。DataContractJsonSerializer可以根据数据契约(DataContract)进行部分字段的序列化,所以我们应该选择它,以下是使用示例:
首先写一个类并定义数据契约,其中属性Property1进行序列化,而属性Property2不进行序列化。(注意此序列化设置会影响WCF生成的客户端代理类)
1 |
<div class="cnblogs_code"><pre><div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;">[DataContract()]<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Class1<br>{<br> [DataMember()]<br> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">string</span><span style="color: #000000;"> Property1 { </span><span style="color: #0000ff;">get</span><span style="color: #000000;">; </span><span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br> [IgnoreDataMember()]<br> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">string</span><span style="color: #000000;"> Property2 { </span><span style="color: #0000ff;">get</span><span style="color: #000000;">; </span><span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br>}</span></div></pre> |
2 |
</div> |
3 |
<p> </p> |
我推荐使用网上比较经典的JSONHelper代码进行序列化,此类内容如下:
public class JSONHelper
{
public static string Serialize<T>(T obj)
{
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, obj);
string retVal = Encoding.Default.GetString(ms.ToArray());
ms.Dispose();
return retVal;
}
public static T Deserialize<T>(string json)
{
T obj = Activator.CreateInstance<T>();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
ms.Close();
ms.Dispose();
return obj;
}
}
而我们进行序列化的代码为:
Class1 item1 = new Class1() { Property1 = "Hello", Property2 = "World" };
Class1 item2 = new Class1() { Property1 = "Richard", Property2 = "Tsuei" };
List<Class1> list=new List<Class1>();
list.Add(item1);
list.Add(item2);
string json=JSONHelper.Serialize (list);
Console.WriteLine(json);
序列化我们可以做了,而且可以使用部分属性的序列化,但第二个问题出现了,如果我有两个页面(视图)使用实体类的不同部分时怎么办?
我也希望有更符合OO的做法,不过抱歉的告诉各位真的没有,但我们可以使用LINQ或反射的方法进行类型转换,示例如下:
var list2=from item in list select new Class2 {Property1=item.Property1,Property3=item.Property2};
string json2=JSONHelper.Serialize(list2.ToList());
Console.WriteLine(json2);
Console.ReadKey();
这里注意Class2也必须是服从数据契约的类型。
注:使用LINQ进行类型转换的好处是强类型在编译期就可以发现错误,使用反射方法则可能产生在运行期才会发现的错误(系统异常)。
我们再强调一下为什么使用JSON而不是XML:
1.从数据长度来讲JSON比XML更加节省
2.从转换性能来讲大部分JSON序列化器都是基于XML序列化器(DataContractJsonSerializer便是如此)
3.在客户端使用上绝大多数Javasciript类库已经支持JSON,在客户端上的序列化性能也不错
4.在客户端使用JSON类型访问简单、方便
来回忆我们此篇的目的:
减少数据传输量
让属性序列化可以定制(根据不同的画面、视图或条件)
讲师:don 浏览数:18
讲师:don 浏览数:24
讲师:don 浏览数:18
讲师:don 浏览数:47
讲师:don 浏览数:26
讲师:don 浏览数:35
讲师:don 浏览数:94
讲师:don 浏览数:97