拦截来自客户端的Web服务的SOAP消息

我有一个与Web服务通信的客户端。 我与之通信的类是通过wsdl.exe生成的C#类。 我现在想记录所有传入和传出的消息。

到目前为止我所做的是编写一个inheritance自动生成的C#类的类,并重写了GetReaderForMessage方法。 这样我可以或多或少地像这样访问传入的消息:

protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize) { System.Xml.XmlReader aReader = base.GetReaderForMessage(message, bufferSize); System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.Load(aReader); string content = doc.InnerXml.ToString(); System.Xml.XmlReader aReader2 = System.Xml.XmlReader.Create(new System.IO.StringReader(content)); return aReader2; } 

显然我对这个解决方案不太满意,因为基本上我正在创建两个xml读者。 一个用于读取SOAP消息的内容,另一个用于返回方法调用方。 另外,我不能用GetWriterForMessage方法做同样的事情。

但可能我只是做起来太困难了。 例如,是否可以直接读取SoapClientMessage对象的内容? 我已经阅读了一些文章,建议我应该在这里使用SoapExtensions,但是从我能理解的情况来看,这只有在我创建的’客户端’本身就是一个Web服务时才会起作用,在这种情况下它不是。

有什么建议?

您需要使用“添加服务引用”而不是“添加Web引用”function来使用此解决方案,如果服务是ASMX或WCF,则可以使用它。 (您需要使用.NET Framework 3.X才能使用此function)

本文将帮助您将服务引用添加到C#项目中。

要拦截请求和响应的XML,请实现以下两个类:

 public class InspectorBehavior : IEndpointBehavior { public string LastRequestXML { get { return myMessageInspector.LastRequestXML; } } public string LastResponseXML { get { return myMessageInspector.LastResponseXML; } } private MyMessageInspector myMessageInspector = new MyMessageInspector(); public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add(myMessageInspector ); } } public class MyMessageInspector : IClientMessageInspector { public string LastRequestXML { get; private set; } public string LastResponseXML { get; private set; } public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { LastResponseXML = reply.ToString(); } public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) { LastRequestXML = request.ToString(); return request; } } 

然后,将呼叫代码更改为:

 MyTestServiceSoapClient client = new MyTestServiceSoapClient(); var requestInterceptor = new InspectorBehavior(); client.Endpoint.Behaviors.Add(requestInterceptor ); client.DoSomething("param1", "param2", "param3"); string requestXML = requestInterceptor.LastRequestXML; string responseXML = requestInterceptor.LastResponseXML; 

****编辑****这与服务器端技术无关,您可以将它与WCF,ASMX,PHP,… Web服务一起使用,我已经测试过: http : //www.w3schools.com/ Web服务/ tempconvert.asmx

并获得以下XML:

requestXML =

   http://tempuri.org/CelsiusToFahrenheit    50    

responseXML的=

     122    

****编辑2 ****

“添加Web引用”不是专用于ASMX而不是ASMX客户端技术,而“添加服务引用”不是WCF客户端技术,您可以使用它们来添加对ASMX,WCF,JSP开发的引用或PHP开发的Web服务,您需要您的应用程序使用.Net framework 3.5来使用“添加服务引用”。

本文提到:

在Visual Studio中使用“添加Web引用”对话框时,将使用WSDL信息生成客户端代理,并将其添加到Visual Studio项目中。 这通常用于ASMX服务,但您也可以使用“添加Web引用”对话框为WCF服务创建客户端代理。 但是,您需要手动键入服务URL,并且生成的代理使用XML序列化,这是唯一支持的序列化类型。 若要为支持数据协定序列化程序的WCF服务创建客户端代理,可以使用Svcutil.exe工具或使用.NET Framework 3.x的Visual Studio开发工具的“添加服务引用”function。