如何解析从文件加载的soap消息?

时间:2017-04-28 13:59:25

标签: c# xml web-services wcf soap

我需要解析从磁盘加载的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]">
...

当我致电该操作时,GetCR&#39;对于Web服务,消息被正确转换为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);
}

.. Deserialize抛出以下异常:分析错误,没有与xml密钥相关联的程序集&ns; ns2 GetCRResponse&#39;。

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

2 个答案:

答案 0 :(得分:1)

更新:

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

答案 1 :(得分:1)

您应该可以使用XmlSerializerSoapReflectionImporter的帮助下完成此操作。

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