再談Silverlight中的對象序列化/反序列化

曾經發過一篇如何在Silveright中利用XmlSerializer序列化對象的文章“Silverlight中的序列化”,限於當時的認識有限,一度以爲silverlight只有這一種辦法,今天意外發現,其實還有更好的方式,特此做一個彙總與比較

1.json序列化方式

silverlight支持json字符串已是衆人皆知的事情,沒啥好說的,有點容易讓人誤導的是:我們在vs的silverlight項目中添加引用時,一眼就能看到System.Runtime.Serialization.Json這個命名空間,於是想當然的以爲json序列化的功能肯定是在這個命名空間下面

結果等你搗鼓半天才發現,其實這下面跟序列化相關的東西,啥也沒有?


可能有朋友注意到了,在最新的.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 { setget; }

        
public int Age { setget; }
    }
}

 

最後比較一下各自的異同:


可以看到,如果:

用json方式序列化以及反序列化,最終會引入50k的"System.Json.dll",序列化後的字節數最少;
XmlSerializer方式,最終會引入314k的"System.Xml.Serialization.dll",序列化後的字節數也最多;
DataContractSerializer方式,默認不需引用額外的程序集,序列化後的字節數高於json方式,但低於XmlSerializer方式


建議:


如果在網絡通訊應用(比如socket編程中),最好使用json方式序列化;
如果想讓最終的xap體積最小(以達到最快加載速度),最好使用DataContractSerializer方式;
一般不建議使用XmlSerializer方式處理對象序列化

 

[轉載請註明來自"菩提樹下的楊過"]

作者:菩提樹下的楊過
出處:http://yjmyzz.cnblogs.com
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章