方案
我正在使用合作伙伴发布的网络服务。我正在实现一个.NET代理客户端。 我想序列化与Web方法调用相关的XML。目的是存储请求详细信息以进行进一步处理/重新处理/记录。
我可以用这样的方式塑造表格,使每个参数对应一个字段。但是通过这种方式,表格将与Web方法签名严格相关。 相反,我想创建一个通用的WebServiceClientRequest表来保存SOAP请求的XML主体。
最终我总是可以添加一个映射每个参数的相关表。
问题
有没有办法序列化SOAP请求的XML内容?
答案 0 :(得分: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();
}
}