手记

【WCF】更改DataContractSerializer的输出格式

    WCF所支持的序列化格式分为Xml和DataContract两种(以下简称Xml格式和DataContract格式)。个人认为,Xml序列化格式是为了达到协议兼容而保留下来的传统格式。比如通过WCF实现基于xup协议的UI架构时,为了与xup协议保持兼容,在设置WCF属性时,建议采用Xml格式;而DataContract格式则是WCF提供的一种新的序列化格式。默认情况下,WCF采用DataContract格式。如需要在WCF中使用Xml格式,我们所要做的事情非常简单:在服务契约接口以及相应的契约方法上应用XmlSerializerFormatAttribute特性,并在使用svcutil.exe实用工具生成客户端代码时带上/ser:XmlSerializer参数。Xml格式和DataContract格式的优缺点大致如下:

  • Xml格式:序列化方式可以通过XmlRootAttribute、XmlElementAttribute以及XmlAttributeAttribute等特性进行控制,也可以使用XmlAttributeOverrides类对序列化方式进行更深层次的自定义,因此它能很方便地兼容已有的通讯协议,使得应用程序符合一定的通讯标准;其缺点就是速度不及DataContract格式,对于需要序列化的成员,必须是公有成员,而且同时实现getter和setter

  • DataContract格式:速度比Xml格式快,因为它正好缺少Xml格式的优点:无法自定义序列化方式。其优点是,相对Xml格式来讲,它支持更多类型的序列化,而且其成员的受访级别可以是受保护的,甚至是私有的;DataContract格式没有Xml格式中类似XmlElementAttribute等控制序列化方式的特性 

    因此,当你的应用程序无需兼容标准协议,并且你不需要对传输的信息作调试时,建议采用DataContract格式。但也有时候我们既希望保证速度,又希望能够在应用程序里输出response的xml信息以便查错;此时,我们会使用DataContractSerializer类来将获得的response信息序列化成xml。当走到这一步时,你会发现,你获得的xml信息会是下面的样子:

view plaincopy to clipboardprint?

  1. <?xml version="1.0" encoding="utf-8"?><ApResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Apworks.UI.Protocols.Response"><SessionId>55b494dc-430d-407e-9c5b-62ff9cc86804</SessionId><Type>Startup</Type><ServerInfo><Name>Apworks UI Experimental Server</Name><Version>1.0</Version></ServerInfo><StartupInfo><WindowList xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><d3p1:string>wndHelloWorld</d3p1:string><d3p1:string>wndComplex</d3p1:string></WindowList></StartupInfo><InSessionInfo><ElementHolderXml i:nil="true" /><EventSelectors i:nil="true" /><UIAttrUpdates i:nil="true" /></InSessionInfo><ShutdownInfo /><ErrorInfo><Message i:nil="true" /></ErrorInfo></ApResponse>  

     其实,我们可以使用XmlWriter和XmlWriterSettings类来自定义xml的输出格式。通过类似下面的代码(注意粗体部分),我们获得了带有缩进效果的xml字符串,增加了xml的可读性。

view plaincopy to clipboardprint?

  1. this.clientProxy.Processed += (sender, e) =>       

  2. {       

  3.     XmlWriterSettings settings = new XmlWriterSettings { Indent = true, Encoding=Encoding.UTF8 };     

  4.   

  5.     settings.IndentChars = "\t";       

  6.     DataContractSerializer s = new DataContractSerializer(typeof(ApResponse));       

  7.     MemoryStream ms = new MemoryStream();       

  8.     XmlWriter writer = XmlWriter.Create(ms, settings);       

  9.     s.WriteObject(writer, e.Response);       

  10.     writer.Flush();       

  11.     writer.Close();       

  12.     string xml = Encoding.ASCII.GetString(ms.ToArray());       

  13.     this.DoProcessed(sender, xml);       

  14. };     

输出效果如下:

view plaincopy to clipboardprint?

  1. <?xml version="1.0" encoding="utf-8"?>      

  2. <ApResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Apworks.UI.Protocols.Response">      

  3.     <SessionId>5fab9547-06c3-4fc9-8e20-43eafa3bb74a</SessionId>      

  4.     <Type>Startup</Type>      

  5.     <ServerInfo>      

  6.         <Name>Apworks UI Experimental Server</Name>      

  7.         <Version>1.0</Version>      

  8.     </ServerInfo>      

  9.     <StartupInfo>      

  10.         <WindowList xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">      

  11.             <d3p1:string>wndHelloWorld</d3p1:string>      

  12.             <d3p1:string>wndComplex</d3p1:string>      

  13.         </WindowList>      

  14.     </StartupInfo>      

  15.     <InSessionInfo>      

  16.         <ElementHolderXml i:nil="true" />      

  17.         <EventSelectors i:nil="true" />      

  18.         <UIAttrUpdates i:nil="true" />      

  19.     </InSessionInfo>      

  20.     <ShutdownInfo />      

  21.     <ErrorInfo>      

  22.         <Message i:nil="true" />      

  23.     </ErrorInfo>      

  24. </ApResponse>    

0人推荐
随时随地看视频
慕课网APP