Silverlight中的序列化


序列化简言之是这样一种能力:能够把复杂的对象(Object)变成某种格式的字符串(常见的格式有xml,string,二进制文件等),这样可以方便的在各种系统中传输或交换(比喻socket编程中的数据包只能用byte[]传输),接收方得到该字符串后,通过反序列化可以还原为复杂对象,进而调用对象的方法或属性 -- 跟反射有点沾边:)

这里先给出一个WinForm的序列化例子,功能为通过打开文件对话框选择一个文件后,构造一个复杂对象,然后序列化为二进制格式,得到该格式后,再反序列化(还原)为复杂对象

Winform中的序列化
  1  using  System;
  2  using  System.IO;
  3  using  System.Runtime.Serialization;
  4  using  System.Runtime.Serialization.Formatters.Binary;
  5  using  System.Text;
  6  using  System.Windows.Forms;
  7 
  8  namespace  SerializeStudy
  9  {
 10       public   partial   class  Form1 : Form
 11      {
 12           public  Form1()
 13          {
 14              InitializeComponent();
 15          }
 16 
 17           private   void  btnSerialize_Click( object  sender, EventArgs e)
 18          {
 19              OpenFileDialog opendlg  =   new  OpenFileDialog();
 20               if  (opendlg.ShowDialog()  ==  DialogResult.OK)
 21              {
 22 
 23                   #region  得到一个包含"文件内容"的Msg对象
 24                  Msg msg  =   new  Msg();
 25                  msg.ReceiverName  =   " jimmy " ;
 26                  msg.SenderName  =   " yjmyzy " ;
 27                  msg.Type  =  MessageType.file;
 28                  FileStream fs  =  opendlg.OpenFile()  as  FileStream;
 29                  msg.Body  =   new   byte [fs.Length];
 30                  fs.Read(msg.Body,  0 , msg.Body.Length);
 31                  fs.Close();
 32                   #endregion
 33 
 34                   #region  将Msg对象序列到内存流中
 35                  MemoryStream ms  =   new  MemoryStream();
 36                  BinaryFormatter binaryFormatter  =   new  BinaryFormatter();
 37                  binaryFormatter.Serialize(ms, msg);
 38                   #endregion
 39 
 40                   #region  再将内存流转化为byte[]
 41                   byte [] arrMsg  =  ms.ToArray();
 42                  ms.Close();
 43                   #endregion
 44 
 45                  MessageBox.Show( " 序列化成功! " );
 46 
 47                  StringBuilder sb  =   new  StringBuilder();
 48 
 49                   for  ( int  i  =   0 ; i  <  arrMsg.Length; i ++ )
 50                  {
 51                      sb.Append(arrMsg[i].ToString()  +   " , " );
 52                  }
 53 
 54                  textBox1.Text  =  sb.ToString().Trim( ' , ' );
 55              }
 56          }
 57 
 58           private   void  btnDeSerialize_Click( object  sender, EventArgs e)
 59          {
 60               if  (textBox1.Text.Trim().Length  ==   0 ) {  return ; }
 61 
 62               #region  先将textbox1中的内容变成byte[]
 63               string [] arrMsg  =  textBox1.Text.Trim().Split( ' , ' );
 64               byte [] arrBin  =   new   byte [arrMsg.Length];
 65 
 66               for  ( int  i  =   0 ; i  <  arrMsg.Length; i ++ )
 67              {
 68                  arrBin[i]  =   byte .Parse(arrMsg[i]);
 69              }
 70               #endregion
 71 
 72               try
 73              {
 74                  IFormatter formatter  =   new  BinaryFormatter();
 75                  MemoryStream ms  =   new  MemoryStream(arrBin);
 76                  Msg msg  =  formatter.Deserialize(ms)  as  Msg;
 77 
 78                   if  (msg  !=   null )
 79                  {
 80                      MessageBox.Show( " 反序列化成功! "   +  msg.ReceiverName  +   " , "   +  msg.SenderName  +   " , "   +  msg.Type);
 81                  }
 82 
 83              }
 84               catch  (Exception ex)
 85              {
 86                  MessageBox.Show(ex.Message.ToString());
 87              }
 88          }
 89      }
 90 
 91 
 92 
 93       ///   <summary>
 94       ///  消息格式
 95       ///   </summary>
 96      [Serializable]
 97       public   enum  MessageType
 98      {
 99          txt,
100          img,
101          file,
102          unknown
103      }
104 
105       ///   <summary>
106       ///  消息对象
107       ///   </summary>
108      [Serializable]
109       public   class  Msg
110      {
111           private  MessageType _type  =  MessageType.unknown;
112           public  MessageType Type
113          {
114               set  { _type  =  value; }
115               get  {  return  _type; }
116          }
117 
118           public   string  SenderName {  set get ; }
119           public   string  ReceiverName {  set get ; }
120           public   byte [] Body {  set get ; }
121 
122      }
123  }
124 

不过在Silverlight中,传统的序列化方式有很多被精减掉了(比如BinaryFormatter之类),唯一得以保存的只剩下System.Xml.Serialization,所以SL中只能通过xml来序列化对象(虽然xml序列化后的字节数相对Binary有点大,不过我们也别无选择),另外有一点很让人不习惯的是,需要序列化的自定义类中,居然不需要加[Serializable],[DataMember]这类标记!(这一点让我郁闷了好久,还为此在网上疯狂的百度,google为啥sl中不识别Serializable)

1.先定义一个需要序列化的类

自定义类
namespace  SerializeDemo
{
    
///   <summary>
    
///  聊天室消息对象
    
///   </summary>         
     public   class  ChatMessage
    {
        
public   string  SenderName {  set get ; }

        
public   string  ReceiverName {  set get ; }

        
public  MessageType Type {  set get ; }

        
public   byte [] Body {  set get ; }

        
public   enum  MessageType { 
            txt,img,file,unknown
        }
       
    }
}

 

2.序列化/反序列化代码示例:

Xaml部分:

Xaml
< UserControl  x:Class ="SerializeDemo.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:DesignWidth ="640"  d:DesignHeight ="480" >
  
< Grid  x:Name ="LayoutRoot" >
      
< Grid.RowDefinitions >
          
< RowDefinition  Height ="30" />
          
< RowDefinition  Height ="*" />
      
</ Grid.RowDefinitions >
      
< StackPanel  HorizontalAlignment ="Center"  Orientation ="Horizontal" >
          
< Button  x:Name ="btnSerialize"  Content ="序列化"  Width ="80"  Height ="24"  Click ="btnSerialize_Click" />
          
< Button  x:Name ="btnDeSerialize"  Content ="反序列化"  Width ="80"  Margin ="10,0,0,0"  Height ="24"  Click ="btnDeSerialize_Click" />
      
</ StackPanel >
      
< TextBox  Grid.Row ="1"  Text ="TextBox"  TextWrapping ="Wrap"   d:LayoutOverrides ="Height"  x:Name ="txtResult" />         
  
</ Grid >
</ UserControl >

Xaml.cs部分:

Xaml.cs
using  System;
using  System.IO;
using  System.Text;
using  System.Windows;
using  System.Windows.Controls;
using  System.Xml.Serialization;

namespace  SerializeDemo
{
    
public   partial   class  MainPage : UserControl
    {
        
public  MainPage()
        {
            InitializeComponent();
        }

        
private   void  btnSerialize_Click( object  sender, RoutedEventArgs e)
        {
            
#region  得到一个复杂对象
            ChatMessage msg 
=   new  ChatMessage();
            msg.ReceiverName 
=   " jimmy " ;
            msg.SenderName 
=   " yjmyzy " ;
            msg.Type 
=  ChatMessage.MessageType.file;
            msg.Body 
=   new   byte [] {  0 1 0 1  };
            
#endregion

            MemoryStream ms 
=   new  MemoryStream();
            XmlSerializer xml 
=   new  XmlSerializer( typeof (ChatMessage));
            
try
            {
                xml.Serialize(ms, msg);
// 将对象序列化为流
                 byte [] arr  =  ms.ToArray();
                StringBuilder sb 
=   new  StringBuilder();
                
for  ( int  i  =   0 ; i  <  arr.Length; i ++ )
                {
                    sb.Append(arr[i].ToString() 
+   " , " );    
                }
                txtResult.Text 
=  sb.ToString().Trim( ' , ' );
            }
            
catch  (Exception ex) 
            {
                txtResult.Text 
=  ex.Message.ToString();
            }
        }

        
private   void  btnDeSerialize_Click( object  sender, RoutedEventArgs e)
        {
            
if  (txtResult.Text.Trim().Length  ==   0 ) {  return ; }
            
#region  先将txtResult中的内容变成byte[]
            
string [] arrMsg  =  txtResult.Text.Trim().Split( ' , ' );
            
byte [] arrBin  =   new   byte [arrMsg.Length];

            
for  ( int  i  =   0 ; i  <  arrMsg.Length; i ++ )
            {
                arrBin[i] 
=   byte .Parse(arrMsg[i]);
            }
            
#endregion
            MemoryStream ms 
=   new  MemoryStream(arrBin);
            XmlSerializer xml 
=   new  XmlSerializer( typeof (ChatMessage));
            
try
            {
                ChatMessage msg 
=  xml.Deserialize(ms)  as  ChatMessage; // 反序列化为ChatMessage对象
                 if  (msg  !=   null )
                {
                    txtResult.Text 
=   " 反序列化成功! "   +  msg.ReceiverName  +   " , "   +  msg.SenderName  +   " , "   +  msg.Type.ToString();
                }
            }
            
catch  (Exception ex) 
            {
                txtResult.Text 
=  ex.Message.ToString();
            }            
        }
    }
}

 

作者: 菩提树下的杨过
出处: http://yjmyzz.cnblogs.com 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值