热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> Silverlight>>正文内容

Silverlight中的序列化

发布时间:2010年02月23日点击数: 佚名

序列化简言之是这样一种能力:能够把复杂的对象(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 { setget; }  
  119.         public string ReceiverName { setget; }  
  120.         public byte[] Body { setget; }  
  121.  
  122.     }  

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

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

自定义类

  1. namespace SerializeDemo  
  2. {  
  3.     /// <summary>  
  4.     /// 聊天室消息对象  
  5.     /// </summary>          
  6.     public class ChatMessage  
  7.     {  
  8.         public string SenderName { setget; }  
  9.  
  10.         public string ReceiverName { setget; }  
  11.  
  12.         public MessageType Type { setget; }  
  13.  
  14.         public byte[] Body { setget; }  
  15.  
  16.         public enum MessageType {   
  17.             txt,img,file,unknown  
  18.         }  
  19.          
  20.     }  

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

Xaml部分:

  1. <UserControl x:Class="SerializeDemo.MainPage"  
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
  5.     mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">  
  6.   <Grid x:Name="LayoutRoot">  
  7.       <Grid.RowDefinitions>  
  8.           <RowDefinition Height="30"/>  
  9.           <RowDefinition Height="*"/>  
  10.       </Grid.RowDefinitions>  
  11.       <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">  
  12.           <Button x:Name="btnSerialize" Content="序列化" Width="80" Height="24" Click="btnSerialize_Click"/>  
  13.           <Button x:Name="btnDeSerialize" Content="反序列化" Width="80" Margin="10,0,0,0" Height="24" Click="btnDeSerialize_Click"/>  
  14.       </StackPanel>  
  15.       <TextBox Grid.Row="1" Text="TextBox" TextWrapping="Wrap"  d:LayoutOverrides="Height" x:Name="txtResult"/>          
  16.   </Grid>  
  17. </UserControl> 

Xaml.cs部分:

  1. using System;  
  2. using System.IO;  
  3. using System.Text;  
  4. using System.Windows;  
  5. using System.Windows.Controls;  
  6. using System.Xml.Serialization;  
  7.  
  8. namespace SerializeDemo  
  9. {  
  10.     public partial class MainPage : UserControl  
  11.     {  
  12.         public MainPage()  
  13.         {  
  14.             InitializeComponent();  
  15.         }  
  16.  
  17.         private void btnSerialize_Click(object sender, RoutedEventArgs e)  
  18.         {  
  19.             #region 得到一个复杂对象  
  20.             ChatMessage msg = new ChatMessage();  
  21.             msg.ReceiverName = "jimmy";  
  22.             msg.SenderName = "yjmyzy";  
  23.             msg.Type = ChatMessage.MessageType.file;  
  24.             msg.Body = new byte[] { 0, 1, 0, 1 };  
  25.             #endregion  
  26.  
  27.             MemoryStream ms = new MemoryStream();  
  28.             XmlSerializer xml = new XmlSerializer(typeof(ChatMessage));  
  29.             try  
  30.             {  
  31.                 xml.Serialize(ms, msg);//将对象序列化为流  
  32.                 byte[] arr = ms.ToArray();  
  33.                 StringBuilder sb = new StringBuilder();  
  34.                 for (int i = 0; i < arr.Length; i++)  
  35.                 {  
  36.                     sb.Append(arr[i].ToString() + ",");      
  37.                 }  
  38.                 txtResult.Text = sb.ToString().Trim(',');  
  39.             }  
  40.             catch (Exception ex)   
  41.             {  
  42.                 txtResult.Text = ex.Message.ToString();  
  43.             }  
  44.         }  
  45.  
  46.         private void btnDeSerialize_Click(object sender, RoutedEventArgs e)  
  47.         {  
  48.             if (txtResult.Text.Trim().Length == 0) { return; }  
  49.             #region 先将txtResult中的内容变成byte[]  
  50.             string[] arrMsg = txtResult.Text.Trim().Split(',');  
  51.             byte[] arrBin = new byte[arrMsg.Length];  
  52.  
  53.             for (int i = 0; i < arrMsg.Length; i++)  
  54.             {  
  55.                 arrBin[i] = byte.Parse(arrMsg[i]);  
  56.             }  
  57.             #endregion  
  58.             MemoryStream ms = new MemoryStream(arrBin);  
  59.             XmlSerializer xml = new XmlSerializer(typeof(ChatMessage));  
  60.             try  
  61.             {  
  62.                 ChatMessage msg = xml.Deserialize(ms) as ChatMessage;//反序列化为ChatMessage对象  
  63.                 if (msg != null)  
  64.                 {  
  65.                     txtResult.Text = "反序列化成功!" + msg.ReceiverName + "," + msg.SenderName + "," + msg.Type.ToString();  
  66.                 }  
  67.             }  
  68.             catch (Exception ex)   
  69.             {  
  70.                 txtResult.Text = ex.Message.ToString();  
  71.             }              
  72.         }  
  73.     }  

本站热点业务

更多模板/案例展示

关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作