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


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

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

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

    <?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 元数据

    <?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 类

    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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    全球各国各类在轨与退役卫星数量与详细参数信息数据下载网站整理[转]
    土地覆盖土壤类型水体流域数据下载网站整理【转】
    Prometheus Operator配置钉钉告警
    Prometheus Operator自动发现功能修改 prometheus.yml文件
    prometheus operator 监控mysqlexporter
    prometheus operator 监控redisexporter
    Prometheus Operator 安装配置|最新版
    Linux 命令之 lsof 列出当前系统已打开的文件列表
    linux内核编译过程的最终总结版
    Linux内核裁剪的具体步骤
  • 原文地址:https://www.cnblogs.com/danielWise/p/1913169.html
Copyright © 2020-2023  润新知