【问题标题】:How to parse a soap message loaded from a file?如何解析从文件加载的soap消息?
【发布时间】:2017-09-26 16:20:27
【问题描述】:

我需要将从磁盘加载的 SOAP 消息解析为生成的代理的类型。 WCF 在收到来自 http 服务器的消息时会执行此操作,因此我应该能够从磁盘执行此操作。

我使用 WCF 使用 Web 服务,我从远程 WSDL 生成代理客户端。

这是我从网络收到的 XML 结构(使用 System.ServiceModel.MessageLogging 记录),我想将其解析为生成的类 CRResponse。:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:PourtuIntf" xmlns:ns2="ns2:PourtuIntf-IPourtu">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <ns2:GetCRResponse>
         <return>
            <ResultCode>0</ResultCode>
            <CR>
               <Theme SOAP-ENC:arrayType="ns1:ItemType[5]">
                  <item>
                     <Key/>
                     <Section SOAP-ENC:arrayType="ns1:Section[3]">
...

当我调用 Web 服务的“GetCR”操作时,消息被正确转换为 WCF 生成的代理客户端类型 GetCRResponse,但我不知道 WCF 是如何工作的,我需要从磁盘解析文件。

我试图以这种方式解析消息:

  GetCRResponse body;
  using (var xmlReader =  XmlReader.Create("Requests\\CR.xml"))
  {
      Message m = Message.CreateMessage(xmlReader, int.MaxValue, MessageVersion.Soap11);
      body = m.GetBody<GetCRResponse>();
  }

在 GeyBody 方法中引发此异常:

Expected element 'ActGetCRResponse' from namespace 'http://schemas.datacontract.org/2004/07/Pourtu.PourtuClient'.. Detecting 'Element' with name 'ActGetCRResponse', namespace 'urn:PourtuIntf-IPourtu'.

我尝试使用 SoapFormatter:

using ( FileStream fs = new FileStream("Requests\\CR.xml", FileMode.Open) )
{
    SoapFormatter formatter = new SoapFormatter();
    body = (ActGetCRResponse)formatter.Deserialize(fs);
}

..反序列化抛出以下异常:分析错误,没有与 xml 键 'ns2 GetCRResponse' 关联的程序集。

我无法使用 xml 序列化程序反序列化为 GetCRResponse,因为 SOAP-ENC:arrayType 属性需要由 soap 序列化程序解释。

【问题讨论】:

  • 请贴出CR.xml的链接或全部内容,谢谢。
  • @abreneliere 如果基于 SOAP xml 创建一组对象类,我可以通过 XmlSerializer 将 SOAP 消息反序列化为 ActGetCRResponse 对象。如果这有帮助,我可以提供,如果不担心的话:) 使用从 wsdl 生成的代理类只会产生错误或空对象。
  • 是的,我需要解析到代理类,因为我需要使用文件数据调用 Web 服务的操作。

标签: c# xml web-services wcf soap


【解决方案1】:

您应该能够在SoapReflectionImporter 的帮助下使用XmlSerializer 来完成此操作。

var importer = new SoapReflectionImporter("ns2:PourtuIntf-IPourtu");
var mapping = importer.ImportTypeMapping(typeof(GetCRResponse));
var serializer = new XmlSerializer(mapping);
var response = serializer.Deserialize(reader) as GetCRResponse;

SoapReflectionImporter 类提供类型映射到 SOAP 编码的消息部分,如 Web 服务描述中所定义 语言 (WSDL) 文档。仅在 Web 服务或客户端时使用 指定 SOAP 编码,如 SOAP 1.1 的第 5 节所述 规范。

以下命令用于从 WSDL 生成您的客户端合同

SvcUtil.exe IPlotiservice.wsdl /t:code /serviceContract

【讨论】:

【解决方案2】:

更新:

Message m = Message.CreateMessage(XmlReader.Create("C:\\testSvc\\login.xml"), int.MaxValue, MessageVersion.Soap11);
            SoapReflectionImporter importer = new SoapReflectionImporter(new SoapAttributeOverrides(), "urn:PlotiIntf-IPloti");
            XmlTypeMapping mapp = importer.ImportTypeMapping(typeof(ActGetCRResponse));
            XmlSerializer xmlSerializer = new XmlSerializer(mapp); 
            var o = (ActGetCRResponse)xmlSerializer.Deserialize(m.GetReaderAtBodyContents());

reference

【讨论】:

  • 感谢您的帮助,但 XmlSerializer 不理解 SOAP-ENC:arrayType 以便将元素的内容解析为正确的类型。
  • @abreneliere 你试过使用DataContractSerializer吗?
  • 是的,我为它添加了另一个帖子:stackoverflow.com/questions/43741674/…
猜你喜欢
  • 2012-07-11
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多