曾经发过一篇如何在Silveright中利用XmlSerializer序列化对象的文章“Silverlight中的序列化”,限于当时的认识有限,一度以为silverlight只有这一种办法,今天意外发现,其实还有更好的方式,特此做一个汇总与比较
1.json序列化方式
silverlight支持json字符串已是众人皆知的事情,没啥好说的,有点容易让人误导的是:我们在vs的silverlight项目中添加引用时,一眼就能看到System.Runtime.Serialization.Json这个命名空间,于是想当然的以为json序列化的功能肯定是在这个命名空间下面
![再谈Silverlight中的对象序列化/反序列化](http://img.e-com-net.com/image/product/82af8084316144bc8af2fd4c298be203.jpg)
结果等你捣鼓半天才发现,其实这下面跟序列化相关的东西,啥也没有?
![再谈Silverlight中的对象序列化/反序列化](http://img.e-com-net.com/image/product/aba4f6d4f1e642ee8a1096659b9460a8.jpg)
可能有朋友注意到了,在最新的.net4.0中,这个命名空间下貌似有json序列化功能了,但在sl4.0正式发布前,sl3.0(及以下版本)还是没办法玩的,其实silverlight3.0中是可以json序列化对象的,正确的程序集在System.ServiceModel.Web这个下面,所以只要添加System.ServiceModel.Web引用即可(代码见本文最后)
另外CodePlex开源项目上也有一个Json的开源项目 http://json.codeplex.com/ 同样可用于Silverlight的序列化
2.XmlSerializer序列化方式
这个在上篇文章里已经讲过了,不再重复
3.DataContractSerializer序列化方式
这个在命名空间System.Runtime.Serialization下
下面演示了三种方式的对象序列化与反序列化,值得一提的是:silverlight中不管用哪一种方式序列化,对象的类定义中都无需添加[DataContract],[DataMember],[Serializeable]之类的标记--前提是对象成员都是string,int之类的基本类型!
silverlight演示:
XAML部分代码:
<
UserControl
x:Class
="SlSerialize.MainPage"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable
="d"
d:DesignHeight
="300"
d:DesignWidth
="400"
>
<
Grid
x:Name
="LayoutRoot"
Background
="White"
>
<
Grid.RowDefinitions
>
<
RowDefinition
></
RowDefinition
>
<
RowDefinition
Height
="30"
></
RowDefinition
>
</
Grid.RowDefinitions
>
<
TextBox
x:Name
="txtResult"
Grid.Row
="0"
HorizontalAlignment
="Stretch"
VerticalAlignment
="Stretch"
TextWrapping
="Wrap"
></
TextBox
>
<
StackPanel
Orientation
="Horizontal"
Grid.Row
="1"
HorizontalAlignment
="Center"
VerticalAlignment
="Center"
Height
="23"
>
<
Button
Content
="Json序列化"
Name
="btnJson"
Click
="btnJson_Click"
/>
<
Button
Content
="Xml序列化"
Name
="btnXml"
Click
="btnXml_Click"
Margin
="5,0,0,0"
/>
<
Button
Content
="二进制序列化"
Name
="btnBin"
Click
="btnBin_Click"
Margin
="5,0,0,0"
/>
</
StackPanel
>
</
Grid
>
</
UserControl
>
CS部分代码:
using
System.IO;
using
System.Json;
using
System.Runtime.Serialization;
using
System.Runtime.Serialization.Json;
using
System.Text;
using
System.Windows;
using
System.Windows.Controls;
using
System.Xml.Serialization;
namespace
SlSerialize
{
public
partial
class
MainPage : UserControl
{
Person _person;
public
MainPage()
{
InitializeComponent();
this
.Loaded
+=
new
RoutedEventHandler(MainPage_Loaded);
}
void
MainPage_Loaded(
object
sender, RoutedEventArgs e)
{
_person
=
new
Person() { Name
=
"
菩提树下的\
"
杨过\
""
, Age
=
30
};
}
private
void
btnJson_Click(
object
sender, RoutedEventArgs e)
{
//
json序列化开始
MemoryStream ms
=
new
MemoryStream();
DataContractJsonSerializer ser
=
new
DataContractJsonSerializer(
typeof
(Person));
ser.WriteObject(ms, _person);
byte
[] json
=
ms.ToArray();
ms.Close();
string
jsonString
=
Encoding.UTF8.GetString(json,
0
, json.Length);
//
序列化得到的字符串
//
json字符串解析(相当于反序列化)
JsonValue jsonv
=
JsonObject.Parse(jsonString);
Person pTest
=
new
Person() { Age
=
int
.Parse(jsonv[
"
Age
"
].ToString()), Name
=
jsonv[
"
Name
"
].ToString() };
//
显示结果
txtResult.Text
=
"
json序列化后的字符串:(长度
"
+
jsonString.Length
+
"
)\n
"
+
jsonString
+
"
\n\n反序列化后的结果:\nAge=
"
+
pTest.Age
+
"
,Name=
"
+
pTest.Name;
}
private
void
btnXml_Click(
object
sender, RoutedEventArgs e)
{
//
xml序列化开始
MemoryStream ms
=
new
MemoryStream();
XmlSerializer xml
=
new
XmlSerializer(
typeof
(Person));
xml.Serialize(ms, _person);
//
xml序列化的关键代码
byte
[] arr
=
ms.ToArray();
ms.Close();
string
xmlString
=
Encoding.UTF8.GetString(arr,
0
,arr.Length);
ms.Close();
//
xml反序列化
MemoryStream ms2
=
new
MemoryStream(Encoding.UTF8.GetBytes(xmlString));
XmlSerializer xml2
=
new
XmlSerializer(
typeof
(Person));
Person pTest
=
xml.Deserialize(ms2)
as
Person;
//
xml反序列化的关键代码
ms2.Close();
//
显示反序列化后的结果
txtResult.Text
=
"
xml序列化后的字符串:(长度
"
+
xmlString.Length
+
"
)\n
"
+
xmlString
+
"
\n\n反序列化后的结果:\nAge=
"
+
pTest.Age
+
"
,Name=
"
+
pTest.Name;
}
private
void
btnBin_Click(
object
sender, RoutedEventArgs e)
{
//
DataContract方式序列化
MemoryStream ms
=
new
MemoryStream();
DataContractSerializer ser
=
new
DataContractSerializer(
typeof
(Person));
ser.WriteObject(ms, _person);
byte
[] array
=
ms.ToArray();
ms.Close();
string
_serializeString
=
Encoding.UTF8.GetString(array,
0
, array.Length);
//
反序列化
DataContractSerializer ser2
=
new
DataContractSerializer(
typeof
(Person));
MemoryStream ms2
=
new
MemoryStream(Encoding.UTF8.GetBytes(_serializeString));
Person pTest
=
ser2.ReadObject(ms2)
as
Person;
//
显示反序列化后的结果
txtResult.Text
=
"
DataContract序列化后的字符串:(长度
"
+
_serializeString.Length
+
"
)\n
"
+
_serializeString
+
"
\n\n反序列化后的结果:\nAge=
"
+
pTest.Age
+
"
,Name=
"
+
pTest.Name;
}
}
///
<summary>
///
测试类
///
</summary>
public
class
Person
{
public
string
Name {
set
;
get
; }
public
int
Age {
set
;
get
; }
}
}
最后比较一下各自的异同:
![再谈Silverlight中的对象序列化/反序列化](http://img.e-com-net.com/image/product/71b13e054b8c45a98c84a66a561dccd3.jpg)
可以看到,如果:
用json方式序列化以及反序列化,最终会引入50k的"System.Json.dll",序列化后的字节数最少;
XmlSerializer方式,最终会引入314k的"System.Xml.Serialization.dll",序列化后的字节数也最多;
DataContractSerializer方式,默认不需引用额外的程序集,序列化后的字节数高于json方式,但低于XmlSerializer方式
建议:
如果在网络通讯应用(比如socket编程中),最好使用json方式序列化;
如果想让最终的xap体积最小(以达到最快加载速度),最好使用DataContractSerializer方式;
一般不建议使用XmlSerializer方式处理对象序列化
[转载请注明来自"菩提树下的杨过"]