简体   繁体   English

.NET Web服务客户端。 获取SOAP请求的XML内容

[英].NET Web Service client. Get the XML content of the SOAP request

Scenario 脚本

I am consuming a web service published by a partner. 我正在消费由合作伙伴发布的Web服务。 I am implementing a .NET proxy client. 我正在实现.NET代理客户端。 I would like to serialize the XML related to a web method invocation. 我想序列化与Web方法调用相关的XML。 The aim is to store the request details for further processing/re-processing/logging. 目的是存储请求详细信息,以进行进一步处理/重新处理/记录。

I could shape the table in such a way that each parameter correspond to a field. 我可以通过使每个参数对应一个字段的方式来调整表格的形状。 But in this way the table would be strictly related to the web method signature. 但是通过这种方式,该表将与Web方法签名严格相关。 Instead I would like to create a general WebServiceClientRequest table that holds the XML body of the SOAP request. 相反,我想创建一个通用的WebServiceClientRequest表,其中包含SOAP请求的XML主体。

Eventually I can always add a related table that maps each parameter. 最终,我总是可以添加一个映射每个参数的相关表。

Question

Is there a way to serialize the XML content of the SOAP request? 有没有一种方法可以序列化SOAP请求的XML内容?

There is a way indeed. 确实有办法。 The idea is to use SOAP extensions, as described in the MSDN article: Walkthrough: Altering the SOAP Message Using SOAP Extensions . 想法是使用SOAP扩展,如MSDN文章中所述: 演练:使用SOAP扩展更改SOAP消息

Then I used a custom DAL manager to store the SOAP messages into the DB. 然后,我使用了一个自定义的DAL管理器将SOAP消息存储到数据库中。

Here are the details. 这是详细信息。

public class SOAPTraceDB : SoapExtension
{
    private Stream oldStream;
    private Stream newStream;
    private string ConnectionString;

    private Int32 RequestId;

    // 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 object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return null;
    }

    // The SOAP extension was configured to run using a configuration file
    // instead of an attribute applied to a specific XML Web service
    // method.
    public override object GetInitializer(Type WebServiceType)
    {
        // Return a db table to log the trace information to, based on the type.
        return MyConfigurationManager.GetAppSetting<string>("SOAPTraceLoggerConnectionString");

    }

    public override void Initialize(object initializer)
    {
        ConnectionString = (string)initializer;
    }

    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                WriteRequest(message);
                break;
            case SoapMessageStage.BeforeDeserialize:
                WriteResponse(message);
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
            default:
                throw new Exception("invalid stage");
        }
    }

    public void WriteRequest(SoapMessage message)
    {
        newStream.Position = 0;
        Stream s = new MemoryStream();

        Copy(newStream, s);
        RequestId = MyDALStaticManager.WriteMessage(DateTime.Now, SOAPMessageType.request, StreamToString(s));
        s.Close();
        newStream.Position = 0;
        Copy(newStream, oldStream);

    }

    public void WriteResponse(SoapMessage message)
    {
        Stream s = new MemoryStream();

        Copy(oldStream, newStream);
        newStream.Position = 0;
        Copy(newStream, s);
        MyDALStaticManager.WriteMessage(DateTime.Now, SOAPMessageType.response, StreamToString(s), RequestId);
        newStream.Position = 0;
        s.Close();
    }

    private string StreamToString(Stream s)
    {
        string res = string.Empty;
        s.Position = 0;

        StreamReader r = new StreamReader(s);

        //SQL Server accept only utf-16 encoding. Is there a better way to set up the stream encoding? utf-16 is not featured among the System.Text.Encoding
        res = r.ReadToEnd().Replace("encoding=\"utf-8\"", "encoding=\"utf-16\"");
        r.Close();

        return res;
    }

    private void Copy(Stream from, Stream to)
    {
        TextReader reader = new StreamReader(from);
        TextWriter writer = new StreamWriter(to);

        string str = reader.ReadToEnd();

        str = XmlUtils.FormatXml(str);

        writer.WriteLine(str);
        writer.Flush();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM