c# – 如何从WCF服务端捕获传入和传出的XML
在我的解决方案中,我有三个项目.一个是WCF服务,另一个是我调用Web服务的
Winforms应用程序,最后一个是类库,其中类已经设计了扩展soap扩展类.
我的目标是捕捉反应和当我从Winforms应用程序调用WCF服务时请求xml.当我尝试捕获xml时,我得到对象引用未设置错误. 这是我的类库源代码. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Services; using System.Web.Services.Protocols; using System.IO; using System.Net; using System.Xml; namespace SoapLogger { public class TraceExtension : SoapExtension { private Stream oldStream; private Stream newStream; private static XmlDocument xmlRequest; /// <summary> /// Gets the outgoing XML request sent to PayPal /// </summary> public static XmlDocument XmlRequest { get { return xmlRequest; } } private static XmlDocument xmlResponse; /// <summary> /// Gets the incoming XML response sent from PayPal /// </summary> public static XmlDocument XmlResponse { get { return xmlResponse; } } /// <summary> /// Save the Stream representing the SOAP request /// or SOAP response into a local memory buffer. /// </summary> /// <param name="stream"> /// <returns></returns> public override Stream ChainStream(Stream stream) { oldStream = stream; newStream = new MemoryStream(); return newStream; } /// <summary> /// If the SoapMessageStage is such that the SoapRequest or /// SoapResponse is still in the SOAP format to be sent or received,/// save it to the xmlRequest or xmlResponse property. /// </summary> /// <param name="message"> public override void ProcessMessage(SoapMessage message) { switch (message.Stage) { case SoapMessageStage.BeforeSerialize: break; case SoapMessageStage.AfterSerialize: xmlRequest = GetSoapEnvelope(newStream); CopyStream(newStream,oldStream); break; case SoapMessageStage.BeforeDeserialize: CopyStream(oldStream,newStream); xmlResponse = GetSoapEnvelope(newStream); break; case SoapMessageStage.AfterDeserialize: break; } } /// <summary> /// Returns the XML representation of the Soap Envelope in the supplied stream. /// Resets the position of stream to zero. /// </summary> /// <param name="stream"> /// <returns></returns> private XmlDocument GetSoapEnvelope(Stream stream) { XmlDocument xml = new XmlDocument(); stream.Position = 0; StreamReader reader = new StreamReader(stream); xml.LoadXml(reader.ReadToEnd()); stream.Position = 0; return xml; } /// <summary> /// Copies a stream. /// </summary> /// <param name="from"> /// <param name="to"> private void CopyStream(Stream from,Stream to) { TextReader reader = new StreamReader(from); TextWriter writer = new StreamWriter(to); writer.WriteLine(reader.ReadToEnd()); writer.Flush(); } #region NoOp /// <summary> /// Included only because it must be implemented. /// </summary> /// <param name="methodInfo"> /// <param name="attribute"> /// <returns></returns> public override object GetInitializer(LogicalMethodInfo methodInfo,SoapExtensionAttribute attribute) { return null; } /// <summary> /// Included only because it must be implemented. /// </summary> /// <param name="WebServiceType"> /// <returns></returns> public override object GetInitializer(Type WebServiceType) { return null; } /// <summary> /// Included only because it must be implemented. /// </summary> /// <param name="initializer"> public override void Initialize(object initializer) { } #endregion NoOp } 以下是我从Winforms应用程序调用Web服务的方法: private void button1_Click(object sender,EventArgs e) { using (ServiceRef.TestServiceSoapClient oService = new ServiceRef.TestServiceSoapClient()) { textBox1.Text = oService.HelloWorld("Sudip"); var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml; var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml; } } 这两行导致对象引用错误 var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml; var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml; 我只是想不通为什么我会收到错误. Winforms应用程序有一个app.config,我在其中注册我的类库程序集以捕获xml.这是我的app.config详细信息 <?xml version="1.0"?> <configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="TestServiceSoap"/> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:6804/Service1.asmx" binding="basicHttpBinding" bindingConfiguration="TestServiceSoap" contract="ServiceRef.TestServiceSoap" name="TestServiceSoap"/> </client> </system.serviceModel> <system.web> <compilation debug="true" targetFramework="4.0" /> <webServices> <soapExtensionTypes> <add type="SoapLogger.TraceExtension,SoapLogger" priority="1" group="0" /> </soapExtensionTypes> </webServices> </system.web> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration> 当我搜索谷歌只是为了知道如何捕获请求/响应xml然后我得到了这么多文章.我跟着很多但没什么作用. 我跟着这个网址来完成工作http://jramirezdev.net/blog/c-tip-capturar-los-mensajes-soap-de-un-servicio-asmx-que-hemos-referenciado 我不清楚是什么样的错误.我在我的类库方法中的每个方法都设置了断点,但是当web服务调用时,没有在类库中执行方法.我不想使用任何像wireshark,fiddler这样的工具来捕获请求/响应xml,而不是想以编程方式做同样的事情. 那么请指导我,我的错误是什么?为什么我得到对象引用没有设置错误?请查看我的代码或转到网址链接并告诉我我的方法有什么问题 解决方法
导致该错误是因为访问它们时尚未初始化xmlRequest / xmlResponse.因此,尝试检查null,或为它们创建默认实例.
从您的代码中,它们仅在ProcessMessage(SoapMessage消息){}中初始化,确保在调用之前调用该方法 var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml; var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml; 希望这可以帮助. 编辑: 在仔细检查了您的代码之后,我意识到您编写的扩展(SoapExtension)是针对ASP.NET XML Web服务的,并且它与WCF服务没有业务关系. 要检查请求并在WCF服务中进行回复,可以通过实现System.ServiceModel.Dispatcher.IDispatchMessageInspector来扩展服务端的调度程序. 你可以在这里找到这个例子http://msdn.microsoft.com/en-us/library/ms733104%28v=vs.100%29.aspx (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |