我是WCF的新手。我为它开发了一个WCF服务和客户端。服务方法将检索使用自定义XML序列化程序的自定义数据。我读过,在这种情况下,合同方法应标有[XmlSerializerFormat]
:
[ServiceContract]
[XmlSerializerFormat]
public interface ITSService
{
[OperationContract]
[XmlSerializerFormat]
ProtocolDocument GetReferenceData(string referenceType, SerializableDictionary<string, string> args);
ProtocolDocument
实施IXmlSerializable
:
[XmlRoot("protocol", Namespace = Protocol30Namespace)]
[Type(Name = "protocol", Namespace = Protocol30Namespace)]
public class ProtocolDocument : ProtocolElement, ICloneable, IXmlSerializable
VS 2010默认选择wsHttpBinding
。我不需要安全,所以我把它关掉了。
以下是服务配置:
<services>
<service name="MyNamespace.TSService"
behaviorConfiguration="MyNamespace.TSServiceBehavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:51944/TSService.svc" />
</baseAddresses>
</host>
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="nonSecurityWSHttpBinding"
contract="MyNamespace.ITSService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyNamespace.TSServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="nonSecurityWSHttpBinding">
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
然后我为此服务生成了客户端,但结果无法反序列化。 Fiddler说,SOAP将序列化数据包装到GetReferenceDataResult
和GetReferenceDataResponse
:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/ITourSystemService/GetReferenceDataResponse</a:Action>
<a:RelatesTo>urn:uuid:3d7f6dc0-4961-4bc5-b1fc-c9997af9fbd4</a:RelatesTo>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetReferenceDataResponse xmlns="http://tempuri.org/">
<GetReferenceDataResult>
<header version="3.0" language="Russian"/>
<references/>
</GetReferenceDataResult>
</GetReferenceDataResponse>
</s:Body>
</s:Envelope>
但缺少根元素!我该怎么办?
PS序列化impl:
void IXmlSerializable.ReadXml(XmlReader reader)
{
var serializer = new ProtocolDocumentXmlSerializer();
serializer.Deserialize(this, reader);
}
void IXmlSerializable.WriteXml(XmlWriter writer)
{
//
// Serialize everything except the root element, because it was already written by .NET XML-serialization mechanism
var xmlSerializationFlags = XmlSerializationFlags.All & ~XmlSerializationFlags.IncludeRootElement;
var serializer = new ProtocolDocumentXmlSerializer();
serializer.Serialize(this, writer, xmlSerializationFlags);
}
Xml序列化效果很好。它已经在使用中。我想我的WCF配置错了。
答案 0 :(得分:0)
您似乎明确告诉它忽略WriteXml方法中的根元素 - 这就是为什么没有根元素
var xmlSerializationFlags = XmlSerializationFlags.All & ~XmlSerializationFlags.IncludeRootElement;
如果无法使反序列化工作,您可以始终使用Message作为客户端契约中的返回类型在XML级别工作,然后对消息调用GetReaderAtBody,将数据加载到XElement并使用LINQ to XML转换将XML转换为在客户端使用的对象