【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. };     

输出效果如下:

  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>    
posted @ 2009-05-22 09:40  dax.net  阅读(1591)  评论(1编辑  收藏  举报