首页 > 代码库 > 序列化与反序列化
序列化与反序列化
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; } } }}
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
序列化与反序列化