2013-07-03 195 views
1

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

我正在使用由合作伙伴发布的Web服务。我正在实现一个.NET代理客户端。 我想序列化与Web方法调用相关的XML。目的是为了进一步处理/重新处理/记录而存储请求细节。

我可以用这样一种方式塑造桌子,使每个参数对应一个字段。但是通过这种方式,表格将严格与Web方法签名相关。 相反,我想创建一个通用的WebServiceClientRequest表,它包含SOAP请求的XML正文。

最终我总是可以添加一个映射每个参数的相关表。

问题

有没有办法序列化SOAP请求的XML内容?

+0

这是一个WCF服务,还是一个传统的ASMX服务? –

+0

据我所知这是一个AXIX网络服务。 –

+0

什么是“AXIX”? –

回答

2

确实有一种方法。 这个想法是使用SOAP扩展,如MSDN文章中所述:Walkthrough: Altering the SOAP Message Using SOAP Extensions

然后我使用自定义的DAL管理器将SOAP消息存储到数据库中。

这是细节。

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(); 
    } 
} 
相关问题