加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何从WCF服务端捕获传入和传出的XML

发布时间:2020-12-15 19:38:55 所属栏目:百科 来源:网络整理
导读:在我的解决方案中,我有三个项目.一个是WCF服务,另一个是我调用Web服务的 Winforms应用程序,最后一个是类库,其中类已经设计了扩展soap扩展类. 我的目标是捕捉反应和当我从Winforms应用程序调用WCF服务时请求xml.当我尝试捕获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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读