zoukankan      html  css  js  c++  java
  • 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"?>
    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 类

    001using System;
    002using System.Collections.Generic;
    003using System.Linq;
    004using System.Text;
    005using System.Xml.Serialization;
    006using System.Xml;
    007using System.Xml.Schema;
    008using System.IO;
    009 
    010namespace 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/
     

  • 相关阅读:
    CF1051D Bicolorings dp
    loj2480 [CEOI2017]One-Way Streets 边双+树上差分
    有趣的支配树
    AtCoder Regular Contest 81
    [BZOJ5305][HAOI2018]苹果树(DP)
    [BZOJ4699]树上的最短路(最短路+线段树)
    [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)
    [Luogu4724][模板]三维凸包(增量构造法)
    [BZOJ5317][JSOI2018]部落战争(闵可夫斯基和)
    [WC2014]时空穿梭(莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/llbofchina/p/2094161.html
Copyright © 2011-2022 走看看