C# · 12月 25, 2021

c# – 如何访问SOAP响应

(如果有什么需要澄清/更多的细节请让我知道.)

我有一个应用程序(C#,2. *框架)与使用SOAP的第三方Web服务接口.我使用thinktecture的WSCF加载项与提供的WSDL来创建客户端实现.由于我无法控制的原因,SOAP消息交换使用WSE2.0作为安全性(必须修改thinctecture实现以包括WSE2.0引用).除了’正常’数据包之外,我附加一个存储的X509证书和一个二进制安全令牌,从前一次调用到另一个Web服务.我们正在使用某种类型的SSL加密 – 我不知道细节.

所有必要的序列化/反序列化都包含在Web服务客户端中 – 这意味着在调用客户端之后控制返回给我时,SOAP响应中包含的整个XML字符串对我来说是不可用的 – 只是反序列化的组件.不要误会我 – 我认为这很好,因为这意味着我不用自己去做.

然而,为了让我有一些值得存储/归档的东西,我不得不重新序列化根元素的数据.这似乎是浪费资源,因为我的结果是SOAP响应.

现在我的问题:
如何访问SOAP响应的“清除”版本,以便我不必重新序列化所有的存储/归档?

编辑 – 我的应用程序是一个作为网络服务运行的“无形”Windows应用程序 – 由WebsphereMQ客户端触发器监视器触发.我不认为ASP.NET解决方案将适用.

编辑 – 由于迄今为止的共识是,我的应用程序是否是ASP.NET并不重要,那么我将给CodeMelt(和扩展Chris的)解决方案一个镜头.

解决方法 您可以利用现有WSE2.0框架中的SoapExtension拦截服务器的响应. public class MyClientSOAPExtension : SoapExtension{ Stream oldStream; Stream newStream; // Save the Stream representing the SOAP request or SOAP response into // a local memory buffer. public override Stream ChainStream( Stream stream ) { oldStream = stream; newStream = new MemoryStream(); return newStream; } public override void ProcessMessage(SoapMessage message) { switch (message.Stage) { case SoapMessageStage.BeforeDeserialize: // before the XML deserialized into object. break; case SoapMessageStage.AfterDeserialize: break; case SoapMessageStage.BeforeSerialize: break; case SoapMessageStage.AfterSerialize: break; default: throw new Exception(“Invalid stage…”); } }}

在SoapMessageStage的舞台上,
您可以从旧版读取想要的数据(例如使用XmlReader).
然后将预期数据存储在某个地方供您自己使用,也需要
将旧的流数据转发到新流,以便后期的Web服务使用数据,例如将XML反序列化为对象.

The sample of logging all the traffic for the web service from MSDN