Silverlight中的序列化

时间:2022-04-23
本文章向大家介绍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 }

不过在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();
             }            
         }
     }
 }