[英]Logging for C# Webservices
我們正在使用Web服務。 我們使用wsdl.exe生成客戶端代理。
我們如何保留代理發送到Web服務提供商和從Web服務提供商接收的所有基礎XML文件?
目的是通過顯示在系統故障和糾紛發生時確實以正確的格式發送了所有參數來保護自己。
我們只是在發出Web服務請求的應用程序中使用SoapExtension做到了這一點。
整個系統由兩個類組成:一個CopyStream
類,該類提供在讀取/寫入流時將流的內容復制到第二個流的功能,以及一個SoapLogger
類,用於攔截應用程序和日志中的所有SOAP請求和響應。他們到一個文件。
您只需要在app.config文件中注冊它:
<configuration>
<system.web>
<webServices>
<soapExtensionTypes>
<add type="MyNamespace.SoapLogger, MyAssembly" priority="3" group="High" />
</soapExtensionTypes>
</webServices>
</system.web>
</configuration>
為大量的代碼表示歉意,但這是:
/// <summary>
/// Extension to allow logging of SOAP request and response xml.
/// </summary>
public class SoapLogger : SoapExtension
{
private MemoryStream copyStream;
public override Stream ChainStream(Stream stream)
{
this.copyStream = new MemoryStream();
return new CopyStream(stream, copyStream);
}
public override object GetInitializer(Type serviceType)
{
return null;
}
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
public override void Initialize(object initializer)
{
}
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.AfterSerialize:
case SoapMessageStage.AfterDeserialize:
Log(message);
break;
}
}
private void Log(SoapMessage message)
{
string messageType;
if (message.Stage == SoapMessageStage.AfterDeserialize)
{
messageType = message is SoapServerMessage ? "SoapRequest" : "SoapResponse";
}
else
{
messageType = message is SoapServerMessage ? "SoapResponse" : "SoapRequest";
}
StreamReader reader = new StreamReader(new MemoryStream(this.copyStream.ToArray()));
Logger.Log(string.Format(
"{0} ({1}):\r\n{2}",
messageType,
message.MethodInfo.Name,
reader.ReadToEnd()
));
}
}
/// <summary>
/// Implementation of a stream that wraps an existing stream while copying anything written
/// or read to another stream.
/// </summary>
public class CopyStream : Stream
{
public Stream BaseStream
{
get
{
return this.baseStream;
}
}
private Stream baseStream;
public Stream OtherStream
{
get
{
return this.otherStream;
}
}
private Stream otherStream;
public CopyStream(Stream BaseStream, Stream OtherStream)
{
if (BaseStream == null)
{
throw new ArgumentNullException("BaseStream");
}
if (OtherStream == null)
{
throw new ArgumentNullException("OtherStream");
}
this.baseStream = BaseStream;
this.otherStream = OtherStream;
}
public override bool CanRead
{
get
{
return this.BaseStream.CanRead;
}
}
public override bool CanSeek
{
get
{
return this.BaseStream.CanSeek;
}
}
public override bool CanWrite
{
get
{
return this.BaseStream.CanWrite;
}
}
public override void Flush()
{
this.BaseStream.Flush();
}
public override long Length
{
get
{
return this.BaseStream.Length;
}
}
public override long Position
{
get
{
return this.BaseStream.Position;
}
set
{
this.BaseStream.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
int returnValue = BaseStream.Read(buffer, offset, count);
this.otherStream.Write(buffer, offset, returnValue);
return returnValue;
}
public override long Seek(long offset, SeekOrigin origin)
{
try
{
this.OtherStream.Seek(offset, origin);
}
catch { }
return BaseStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
try
{
this.OtherStream.SetLength(value);
}
catch { }
this.BaseStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
try
{
this.OtherStream.Write(buffer, offset, count);
}
catch { }
this.BaseStream.Write(buffer, offset, count);
}
}
它尚未經過性能/壓力測試,但似乎還不錯- 希望流復制完成的方式應減輕任何性能影響。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.