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?
<?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?
this.clientProxy.Processed += (sender, e) =>
{
XmlWriterSettings settings = new XmlWriterSettings { Indent = true, Encoding=Encoding.UTF8 };
settings.IndentChars = "\t";
DataContractSerializer s = new DataContractSerializer(typeof(ApResponse));
MemoryStream ms = new MemoryStream();
XmlWriter writer = XmlWriter.Create(ms, settings);
s.WriteObject(writer, e.Response);
writer.Flush();
writer.Close();
string xml = Encoding.ASCII.GetString(ms.ToArray());
this.DoProcessed(sender, xml);
};
输出效果如下:
view plaincopy to clipboardprint?
<?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>5fab9547-06c3-4fc9-8e20-43eafa3bb74a</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>