WCF 第六章 序列化和编码 为自定义序列化使用XmlSerializer
2010-12-21 22:04 DanielWise 阅读(2360) 评论(1) 编辑 收藏 举报DataContractSerializer是WCF中优先选择的序列化方法。然而,有时你需要使用默认序列化方法以外的方法。一个改变序列化方法的选项是使用XmlSerializer,包括实现自定义序列化的能力,共享类型和支持原有网络服务的能力。对DataContractSerializer,XmlSerializer是WCF集成的一部分。这部分主要查看下XmlSerializer并讨论它如何用来控制XML输出。
DataContractSerialzier总是使用XML元素进行序列化而不是使用XML属性。列表6.31显示了一个使用DataContractSerializer的Employee实例。
列表6.31 使用DataContractSerializer序列化Employee实例
1 2 3 4 5 6 | <?xml version= "1.0" encoding= "utf-16" ?> <EmployeeSurrogated xmlns:i= "http://www.w3.org/2001/XMLSchema-instance" xmlns= "http://schemas.datacontract.org/2004/07/Services" > <employeeID>12345</employeeID> <firstName>Daniel</firstName> <lastName>Dong</lastName> </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 元数据
1 2 3 4 5 6 7 8 9 10 11 | <?xml version= "1.0" encoding= "utf-8" ?> <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" > <xs:complexType name= "Employee" > <xs:sequence> <xs:attribute name= "EmployeeID" type= "xs:int" /> <xs:attribute name= "FirstName" type= "xs:string" /> <xs:attribute name= "LastName" type= "xs:string" /> </xs:sequence> </xs:complexType> <xs:element name= "Employee" nillable= "true" type= "tns:Employee" /> </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 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization; using System.Xml; using System.Xml.Schema; using System.IO; namespace EmployeeSerialization { [XmlSchemaProvider( "MySchema" )] public class Employee : IXmlSerializable { private const string ns = "http://essentialwcf/xmlserialization/" ; private int employeeID; private string firstName; private string lastName; public Employee() { } public Employee( int employeeID, string firstName, string lastName) { this .employeeID = employeeID; this .firstName = firstName; this .lastName = lastName; } public int EmployeeID { get { return employeeID; } set { employeeID = value; } } public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } public static XmlQualifiedName MySchema(XmlSchemaSet schemaSet) { XmlSchema schema = XmlSchema.Read( new StringReader( @"<xs:schema elementFormDefault=""qualified""" + @" xmlns:tns="" + namespace + """ + @" targetNamespace="" + namespace +""" + @" xmlns=""http://www.w3.org/2001/XMLSchema""" + @" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" + @" <xs:element name=""Employee"">" + @"<xs:complexType>" + @" <xs:attribute name=""EmployeeID"" type=""xs:int"" />" + @" <xs:attribute name=""FirstName"" type=""xs:string"" />" + @" <xs:attribute name=""LastName"" type=""xs:string"" />" + @" </xs:complexType>" + @" </xs:element>" + @" </xs:schema>" ), null ); schemaSet.XmlResolver = new XmlUrlResolver(); schemaSet.Add(schema); return new XmlQualifiedName( "Employee" , ns); } public XmlSchema GetSchema() { return null ; } public void ReadXml(XmlReader reader) { while (reader.IsStartElement()) { reader.MoveToContent(); reader.Read(); if (reader.IsStartElement( "Employee" )) { reader.MoveToContent(); reader.Read(); reader.MoveToContent(); } if (reader.IsStartElement( "ID" )) { reader.MoveToContent(); reader.Read(); this .employeeID = reader.ReadContentAsInt(); reader.MoveToContent(); reader.ReadEndElement(); } if (reader.IsStartElement( "FirstName" )) { reader.MoveToContent(); reader.Read(); this .firstName = reader.ReadContentAsString(); reader.MoveToContent(); reader.ReadEndElement(); } if (reader.IsStartElement( "LastName" )) { reader.MoveToContent(); reader.Read(); this .lastName = reader.ReadContentAsString(); reader.MoveToContent(); reader.ReadEndElement(); } } reader.ReadEndElement(); } public void WriteXml(XmlWriter writer) { writer.WriteStartElement( "Employee" ); writer.WriteStartElement( "ID" ); writer.WriteValue( this .employeeID.ToString()); writer.WriteEndElement(); writer.WriteStartElement( "FirstName" ); writer.WriteValue( this .firstName); writer.WriteEndElement(); writer.WriteStartElement( "LastName" ); writer.WriteValue( this .lastName); writer.WriteEndElement(); writer.WriteEndElement(); } } } |
使用XmlSerializer的结果是我们可以与XSD元数据一起工作并作为我们契约的开始点。不使用这个方法可能导致需要写很多代码。
作者:DanielWise
出处:http://www.cnblogs.com/danielWise/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述