0

我是 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 2010wsHttpBinding默认选择。我不需要安全,所以我把它关了。

这是服务配置:

<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 将序列化数据包装到GetReferenceDataResultand中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 配置有问题。

4

1 回答 1

0

您似乎已经明确告诉它在您的 WriteXml 方法中忽略您的根元素 - 这就是为什么没有根元素

var xmlSerializationFlags = XmlSerializationFlags.All & ~XmlSerializationFlags.IncludeRootElement;

如果您无法使反序列化工作,您始终可以在 XML 级别工作,方法是使用 Message 作为客户端合同中的返回类型,然后在消息上调用 GetReaderAtBody,将数据加载到 XElement 并使用 LINQ to XML 将 XML 转换为对象在客户端工作

于 2012-05-15T11:38:11.627 回答