WCF 第六章 序列化和编码 为自定义序列化使用XmlSerializer

DataContractSerializer是WCF中优先选择的序列化方法。然而, 有时你需要使用默认序列化方法以外的方法。一个改变序列化方法的选项是使用XmlSerializer,包括实现自定义序列化的能力,共享类型和支持原有 网络服务的能力。对DataContractSerializer,XmlSerializer是WCF集成的一部分。这部分主要查看下 XmlSerializer并讨论它如何用来控制XML输出。

  DataContractSerialzier总是使用XML元素进行序列化而不是使用XML属性。列表6.31显示了一个使用DataContractSerializer的Employee实例。

列表6.31 使用DataContractSerializer序列化Employee实例

1 <?xml version="1.0" encoding="utf-16"?>
3   <employeeID>12345</employeeID>
4   <firstName>Daniel</firstName>
5   <lastName>Dong</lastName>
6 </EmployeeSurrogated>

 检查序列化XML,你可以数据契约可以使用XML属性被重写。一个使用XML属性而不是XML元素的例子在这里显示:

  <Employee EmployeeID="101" FirstName="Daniel" LastName="Dong" />

XML属性不可能使用DataContractSerializer。DataContractSerializer通过允许XML元素的名字使用 [DataMember]属性确认来提供有限对XML的控制。NetDataContractSerializer本质与 DataContractSerializer是一样的但是支持共享类型信息。这意味着XmlSerializer是唯一的你可以对序列化输出完全控制的 序列化方法。列表6.32用XML属性显示了一段用于Employee类的元数据。

列表6.32 Employee XSD 元数据

01 <?xml version="1.0" encoding="utf-8"?>
02 <xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/EssentialWCF" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/EssentialWCF" xmlns:xs="http://www.w3.org/2001/XMLSchema">
03   <xs:complexType name="Employee">
04     <xs:sequence>
05       <xs:attribute name="EmployeeID" type="xs:int" />
06       <xs:attribute name="FirstName" type="xs:string" />
07       <xs:attribute name="LastName" type="xs:string" />
08     </xs:sequence>
09   </xs:complexType>
10   <xs:element name="Employee" nillable="true" type="tns:Employee" />
11 </xs:schema>

使用属性的自定义XmlSerializer

你可以使用XmlSerializer在两种方式控制XML输出。第一种和最常用的方法是使用System.Xml.Serializer命名空间 下的.NET Framework来指导XmlSerializer如何控制XML输出。默认情况下,XmlSerializer将以XML元素输出公共字段和公共可读 /可写属性。这可以通过[XmlAttribute属性来改变XML属性。默认XmlSerializer将序列化公共字段和公共可读/可写属性除非使用 [XmlIgnore]告诉它不要进行序列化。额外的属性,比如[XmlElement],[XmlRoot],[XmlArray]和 [XmlArrayItem]属性,帮助指导XmlSerializer如何序列化类型。

 

使用IXmlSerializer自定义XmlSerialization

第二个使用XmlSerializer的方法是使用IXmlSerializable接口,一般用在高级场景中,需要对序列化进行完全控制。 IXmlSerializable接口支持三种方法: GetSchema,ReadXml和WriteXml. 在.NET 2.0 中,GetSchema方法被[XmlSchemaProvider]属性取代。另外两个方法是ReadXml和WriteXml.这些方法与用来反序列 化和序列化方法关联。列表6.33描述了这种情况。

列表6.33 使用XML序列化的Employee 类

001 using System;
002 using System.Collections.Generic;
003 using System.Linq;
004 using System.Text;
005 using System.Xml.Serialization;
006 using System.Xml;
007 using System.Xml.Schema;
008 using System.IO;
009  
010 namespace EmployeeSerialization
011 {
012     [XmlSchemaProvider("MySchema")]
013     public class Employee : IXmlSerializable
014     {
015         private const string ns = "http://essentialwcf/xmlserialization/";
016  
017         private int employeeID;
018         private string firstName;
019         private string lastName;
020  
021         public Employee()
022         {
023         }
024  
025         public Employee(int employeeID, string firstName, string lastName)
026         {
027             this.employeeID = employeeID;
028             this.firstName = firstName;
029             this.lastName = lastName;
030         }
031  
032         public int EmployeeID
033         {
034             get { return employeeID; }
035             set { employeeID = value; }
036         }
037  
038  
039         public string FirstName
040         {
041             get { return firstName; }
042             set { firstName = value; }
043         }
044  
045  
046         public string LastName
047         {
048             get { return lastName; }
049             set { lastName = value; }
050         }
051  
052         public static XmlQualifiedName MySchema(XmlSchemaSet schemaSet)
053         {
054             XmlSchema schema = XmlSchema.Read(new StringReader(
055                 @"<xs:schema elementFormDefault=""qualified""" +
056                 @" xmlns:tns="" + namespace + """ +
057                 @" targetNamespace="" + namespace +""" +
058                 @" xmlns=""http://www.w3.org/2001/XMLSchema""" +
059                 @" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" +
060                 @" <xs:element name=""Employee"">" + @"<xs:complexType>" +
061                 @" <xs:attribute name=""EmployeeID"" type=""xs:int"" />" +
062                 @" <xs:attribute name=""FirstName"" type=""xs:string"" />" +
063                 @" <xs:attribute name=""LastName"" type=""xs:string"" />" +
064                 @" </xs:complexType>" +
065                 @" </xs:element>" +
066                 @" </xs:schema>"), null);
067             schemaSet.XmlResolver = new XmlUrlResolver();
068             schemaSet.Add(schema);
069  
070             return new XmlQualifiedName("Employee", ns);
071         }
072  
073         public XmlSchema GetSchema()
074         {
075             return null;
076         }
077  
078         public void ReadXml(XmlReader reader)
079         {
080              
081             while(reader.IsStartElement())
082             {
083                 reader.MoveToContent();
084                 reader.Read();
085  
086                 if (reader.IsStartElement("Employee"))
087                 {
088                     reader.MoveToContent();
089                     reader.Read();
090                     reader.MoveToContent();
091                 }
092                 if (reader.IsStartElement("ID"))
093                 {
094                     reader.MoveToContent();
095                     reader.Read();
096                     this.employeeID = reader.ReadContentAsInt();
097                     reader.MoveToContent();
098                     reader.ReadEndElement();
099                 }
100                 if (reader.IsStartElement("FirstName"))
101                 {
102                     reader.MoveToContent();
103                     reader.Read();
104                     this.firstName = reader.ReadContentAsString();
105                     reader.MoveToContent();
106                     reader.ReadEndElement();
107                 }
108                 if (reader.IsStartElement("LastName"))
109                 {
110                     reader.MoveToContent();
111                     reader.Read();
112                     this.lastName = reader.ReadContentAsString();
113                     reader.MoveToContent();
114                     reader.ReadEndElement();
115                 }
116             }
117             reader.ReadEndElement();
118         }
119  
120         public void WriteXml(XmlWriter writer)
121         {
122             writer.WriteStartElement("Employee");
123  
124             writer.WriteStartElement("ID");
125             writer.WriteValue(this.employeeID.ToString());
126             writer.WriteEndElement();
127  
128             writer.WriteStartElement("FirstName");
129             writer.WriteValue(this.firstName);
130             writer.WriteEndElement();
131  
132             writer.WriteStartElement("LastName");
133             writer.WriteValue(this.lastName);
134             writer.WriteEndElement();
135  
136             writer.WriteEndElement();
137         }
138     }
139 }

  使用XmlSerializer的结果是我们可以与XSD元数据一起工作并作为我们契约的开始点。不使用这个方法可能导致需要写很多代码。


=======
转载自
作者:DanielWise
出处:http://www.cnblogs.com/danielWise/
 

你可能感兴趣的:(Serialize)