再谈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 { set; get; }

 public int Age { set; get; }
    }
}

最后比较一下各自的异同:

可以看到,如果:

用json方式序列化以及反序列化,最终会引入50k的"System.Json.dll",序列化后的字节数最少; XmlSerializer方式,最终会引入314k的"System.Xml.Serialization.dll",序列化后的字节数也最多; DataContractSerializer方式,默认不需引用额外的程序集,序列化后的字节数高于json方式,但低于XmlSerializer方式

建议: 如果在网络通讯应用(比如socket编程中),最好使用json方式序列化; 如果想让最终的xap体积最小(以达到最快加载速度),最好使用DataContractSerializer方式; 一般不建议使用XmlSerializer方式处理对象序列化

[转载请注明来自"菩提树下的杨过"]

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏vue

委托初级篇——lambda表达式的推导

 public delegate void ConsoleWriteStr(string name,DateTime now);

16820
来自专栏韩伟的专栏

框架设计原则和规范(四)

祝大家平安夜平安,圣诞节快乐! 此文是《.NET:框架设计原则、规范》的读书笔记,本文内容较多,共分九章,将分4天进行推送,今天推送最后两章。 1. 什么是好的...

44540
来自专栏丑胖侠

《Drools7.0.0.Final规则引擎教程》第4章 Query查询之基础

Query查询 首先,我们先来看一下query的语法结构图: ? Query语法提供了一种查询working memory中符合约束条件的FACT对...

27390
来自专栏企鹅号快讯

【新手笔记】关于Split方法

Split,把一个字符串分割成字符串数组。 以前是做C#的,前段时间做安卓开发,用了一下Split方法,发现分割后的长度比预期的少,检查了一下,发现java中的...

24070
来自专栏博客园

.NET Core中延迟单例另一种写法【.NET Core和.NET Framework的beforefieldinit差异】

   前段时间在反编译代码时无意间看到在类中有一个BeforeFieldInit特性,处于好奇的心态查了查这个特性,发现这是一个关于字段初始化时间的特性【提前初...

19240
来自专栏大内老A

通过实例模拟ASP.NET MVC的Model绑定机制:数组

[续《通过实例模拟ASP.NET MVC的Model绑定机制:简单类型+复杂类型]》]基于数组和集合类型的Model绑定机制比较类似,对于绑定参数类型或者参数类...

30890
来自专栏蘑菇先生的技术笔记

探索c#之递归APS和CPS

30870
来自专栏jessetalks

由浅入深表达式树(一)创建表达式树

  为什么要学习表达式树?表达式树是将我们原来可以直接由代码编写的逻辑以表达式的方式存储在树状的结构里,从而可以在运行时去解析这个树,然后执行,实现动态的编辑和...

34340
来自专栏恰童鞋骚年

.NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

开篇:在上一篇中,我们了解了自动属性、隐式类型、自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类、匿名方法以及常用的扩展方法。虽然,都是很常见的东西,...

12630
来自专栏blackheart的专栏

[C#1] 11-接口

接口与继承 CLR规定一个类型只能有一个基类型,这种继承成为单继承; 接口继承是指一个类型继承的是接口中的方法签名,而非方法实现,通常称为实现接口; 接口仅仅是...

21790

扫码关注云+社区

领取腾讯云代金券