【问题标题】:XmlSerialization for custom type in WCF serviceWCF 服务中自定义类型的 XmlSerialization
【发布时间】:2012-05-15 10:22:33
【问题描述】:

我是 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 将序列化数据包装成 GetReferenceDataResultGetReferenceDataResponse

 <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 序列化实现:

 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 配置有问题。

【问题讨论】:

  • 缺少“根元素”是什么意思?你期待看到什么?您正在实现 IXmlSerializable,因此您可以控制序列化
  • 感谢您的及时回复!我希望序列化的字符串将包含根元素
  • schemas.aaa.ru/protocol-v3.0"><header version="3.0" language="Russian" />
  • 你能展示你的 IXmlSerializable iplementation 吗?
  • SOAP 将序列化字符串包装到 GetReferenceDataResult 和 GetReferenceDataResponse 中,并且缺少根元素。所以 serialozer 无法反序列化它。有什么理由阻止它?

标签: wcf c#-4.0 xml-serialization


【解决方案1】:

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

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

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

【讨论】:

  • 抱歉,这个序列化已经在 http-requests 中使用了,我无法更改它。我应该忘记 SOAP 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2010-09-17
  • 2011-04-14
  • 1970-01-01
相关资源
最近更新 更多