首页 > 代码库 > 序列化与反序列化

序列化与反序列化

技术分享
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xml.Serialization;using System.IO;using System.Globalization;namespace SerializeSample{    class Program    {        static void Main(string[] args)        {            XmlSerializer serializer = new XmlSerializer(typeof(TemplateDescription[]));            StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);            List<TemplateDescription> list = new List<TemplateDescription>();            TemplateDescription template = new TemplateDescription("aaa", "bbb", 100);            template.ObjectValue = new int[2] { 1, 2 };            TemplateDescription template2 = new TemplateDescription("mmm", "nnn", 101);            template2.ObjectValue = new byte[2] { 3, 4 };            list.Add(template);            list.Add(template2);            // Serialize            serializer.Serialize(writer, list.ToArray());            File.WriteAllText(@"d:\serialize.txt", writer.ToString());            Console.WriteLine(writer.ToString());            // DeSerialize            TemplateDescription[] test = (TemplateDescription[])serializer.Deserialize(new StringReader(writer.ToString()));            Console.WriteLine(test[0].ToString());        }    }    [XmlInclude(typeof(int[]))]    public class TemplateDescription    {        public TemplateDescription()        {            this.Name = string.Empty;            this.Description = string.Empty;            this.ID = 0;            this.ObjectValue = http://www.mamicode.com/null;        }        public TemplateDescription(string name, string description, int id)        {            this.Name = name;            this.Description = description;            this.ID = id;        }        public string Name { get; set; }        public string Description { get; set; }        public int ID { get; set; }        [XmlElement("Value")]        public object ObjectValue { get; set; }        [XmlIgnore]        public int[] IntegerArrayValue        {            get { return (int[])ObjectValue; }            set { ObjectValue =http://www.mamicode.com/ value; }        }        [XmlIgnore]        public byte[] ByteArrayValue        {            get { return (byte[])ObjectValue; }            set { ObjectValue =http://www.mamicode.com/ value; }        }    }}
View Code

 

xml format的序列化只是针对公有属性。

1. 序列化数组,需要指定特质属性[XmlArrayItem(typeof(...))]。

如果不指定则有可能不能正确序列化,从实验看int数组不指定也可以正确序列化,byte数组就必须得指定。如下:

public class MyClass    {        public int[] IDs { get; set; }        public byte[] BTs { get; set; }        public char Charactor { get; set; }        public MyClass()        {            this.IDs = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };            this.BTs = new byte[] { 121, 122, 123, 124, 255, 201 };            this.Charactor = a;        }    }

序列化结果,BTs看上去不正确,其实是经过了based64编码的结果,是正确的。但是如果想得到显式的结果最好加上[XmlArrayItem(typeof(byte))]。

<?xml version="1.0" encoding="utf-16"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<IDs>
<int>1</int>
<int>2</int>
<int>3</int>
<int>4</int>
<int>5</int>
<int>6</int>
<int>7</int>
<int>8</int>
<int>9</int>
<int>0</int>
</IDs>
<BTs>eXp7fP/J</BTs>
<Charactor>97</Charactor>
</MyClass>

 

加上特制属性:

    public class MyClass    {        public int[] IDs { get; set; }        [XmlArrayItem(typeof(byte))]        public byte[] BTs { get; set; }        public char Charactor { get; set; }        public MyClass()        {            this.IDs = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };            this.BTs = new byte[] { 121, 122, 123, 124, 255, 201 };            this.Charactor = a;        }    }        static void Test5()        {            XmlSerializer serializer = new XmlSerializer(typeof(MyClass));            StringWriter writer = new StringWriter();            MyClass myObject = new MyClass();            serializer.Serialize(writer, myObject);            Console.WriteLine(writer.ToString());        }

序列化正确:

<?xml version="1.0" encoding="utf-16"?><MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  <IDs>    <int>1</int>    <int>2</int>    <int>3</int>    <int>4</int>    <int>5</int>    <int>6</int>    <int>7</int>    <int>8</int>    <int>9</int>    <int>0</int>  </IDs>  <BTs>    <unsignedByte>121</unsignedByte>    <unsignedByte>122</unsignedByte>    <unsignedByte>123</unsignedByte>    <unsignedByte>124</unsignedByte>    <unsignedByte>255</unsignedByte>    <unsignedByte>201</unsignedByte>  </BTs>  <Charactor>97</Charactor></MyClass>

 

2. 当某个需要序列化的field或者property具有不确定的类型时,如果要正确序列化它必须在类型上指定[XmlInclude(typeof(...)),XmlInclude(typeof(...))]属性,标识property可能的类型。

如下,public object ObjectValue { get; set; }属性可能是int[],byte[], 所以TemplateDescription加XmlInclude属性。

    [XmlInclude(typeof(byte[])), XmlInclude(typeof(int[]))]
    public class TemplateDescription

  Notes:

     只加[XmlInclude(typeof(int[]))]也可以正确序列化byte[]数组的情况。

        [XmlInclude(typeof(int[]))]
        public class TemplateDescription

    只不过 byte[]数组序列化为based64编码结果<Value xsi:type="xsd:base64Binary">AwQ=</Value>,请考虑序加[XmlArrayItem(typeof(byte))] 。

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Xml.Serialization; 6 using System.IO; 7 using System.Globalization; 8  9 namespace SerializeSample10 {11     class Program12     {13         static void Main(string[] args)14         {15             XmlSerializer serializer = new XmlSerializer(typeof(TemplateDescription[]));16             StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);17 18             List<TemplateDescription> list = new List<TemplateDescription>();19             TemplateDescription template = new TemplateDescription("aaa", "bbb", 100);20             template.ObjectValue = http://www.mamicode.com/new int[2] { 1, 2 };21             TemplateDescription template2 = new TemplateDescription("mmm", "nnn", 101);22             template2.ObjectValue = http://www.mamicode.com/new byte[2] { 3, 4 };23 24             list.Add(template);25             list.Add(template2);26 27             // Serialize28             serializer.Serialize(writer, list.ToArray());29             File.WriteAllText(@"d:\serialize.txt", writer.ToString());30             Console.WriteLine(writer.ToString());31 32             // DeSerialize33             TemplateDescription[] test = (TemplateDescription[])serializer.Deserialize(new StringReader(writer.ToString()));34             Console.WriteLine(test[0].ToString());35         }36     }37 38     [XmlInclude(typeof(byte[])), XmlInclude(typeof(int[]))]39     public class TemplateDescription40     {41         public TemplateDescription()42         {43             this.Name = string.Empty;44             this.Description = string.Empty;45             this.ID = 0;46             this.ObjectValue = http://www.mamicode.com/null;47         }48 49         public TemplateDescription(string name, string description, int id)50         {51             this.Name = name;52             this.Description = description;53             this.ID = id;54         }55 56         public string Name { get; set; }57         public string Description { get; set; }58         public int ID { get; set; }59 60         [XmlElement("Value")]61         public object ObjectValue { get; set; }62 63         [XmlIgnore]64         public int[] IntegerArrayValue65         {66             get { return (int[])ObjectValue; }67             set { ObjectValue =http://www.mamicode.com/ value; }68         }69 70         [XmlIgnore]71         public byte[] ByteArrayValue72         {73             get { return (byte[])ObjectValue; }74             set { ObjectValue =http://www.mamicode.com/ value; }75         }76     }77 78 }

 

 1 <?xml version="1.0" encoding="utf-16"?> 2 <ArrayOfTemplateDescription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 3   <TemplateDescription> 4     <Name>aaa</Name> 5     <Description>bbb</Description> 6     <ID>100</ID> 7     <Value xsi:type="ArrayOfInt"> 8       <int>1</int> 9       <int>2</int>10     </Value>11   </TemplateDescription>12   <TemplateDescription>13     <Name>mmm</Name>14     <Description>nnn</Description>15     <ID>101</ID>16     <Value xsi:type="xsd:base64Binary">AwQ=</Value>17   </TemplateDescription>18 </ArrayOfTemplateDescription>

 

 二.

注意:当类成员变量中出现不能被序列化的类或接口时候我们要通过

[NonSerialized]   只针对成员变量

[XmlIgnore]   针对成员变量和属性,只针对XML序列化

标记其不被序列化和反序列化

特别注意:要使某属性在XML序列化过程中不被序列化只能使用[XmlIgnore],[NonSerialized]无效

 

三.

 “上午同事问我一个问题,实体序列化时报了一个错:The type ConsoleTest.Item was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically. 分析之后,发现了问题,原来被序列化的实体其中一个Property的类型是Object,但是实例化时给这个Property赋了一个自定义的Item,因此序列化未通过。之后,在Property上加上属性[XmlElement(typeof(Item))]即可序列化成功。
       利用Xml序列化技术进行开发有一段时间了,总结了此应用的一些经验,供网友分享。”

http://blog.csdn.net/henrylubin/article/details/2047671

扩展问题:如果Object在某时刻又被赋值为其他非item对象了呢?Property上加上属性[XmlElement(typeof(Item))]还是不够彻底,最好在类上加

[XmlInclude(typeof(...)), XmlInclude(typeof(...))]

 

 

所有的Attribute Class:

http://msdn.microsoft.com/en-us/library/system.attribute.aspx#inheritanceContinued

序列化与反序列化