如何解析从文件加载的soap消息?
Posted
技术标签:
【中文标题】如何解析从文件加载的soap消息?【英文标题】:How to parse a soap message loaded from a file? 【发布时间】: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的链接或全部内容,谢谢。 这里是整个 CR.xml:dropbox.com/sh/8lnwwg7ed7tunmm/AAD286dN8BHUrF2YYvjbPruna?dl=0,这里是完整的 WSDL:dropbox.com/s/gbdd3w3th0lon04/IPlotiservice.wsdl?dl=0 @abreneliere 如果基于 SOAP xml 创建一组对象类,我可以通过 XmlSerializer 将 SOAP 消息反序列化为 ActGetCRResponse 对象。如果这有帮助,我可以提供,如果不担心的话:) 使用从 wsdl 生成的代理类只会产生错误或空对象。 是的,我需要解析到代理类,因为我需要使用文件数据调用 Web 服务的操作。 【参考方案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
【讨论】:
是的,我添加了一个关于 DataContractSerializer 问题的帖子:***.com/questions/43741674/…【参考方案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
吗?
是的,我为它添加了另一个帖子:***.com/questions/43741674/…以上是关于如何解析从文件加载的soap消息?的主要内容,如果未能解决你的问题,请参考以下文章
PHP SoapClient over selfsigned certificate,SOAP-ERROR:解析WSDL:无法从'https://加载