最近,我正在探索一些方法來記錄我的WCF服務處理的任何請求/響應。WCF消息檢查器不工作
在此之前,我有跟蹤選項的一些不好的經驗。現在,我還不知道如何得到實際的響應和跟蹤請求(我試過svctraceviewer工具,它沒有得到對我有意義的東西)。即使如此,跟蹤文件已生成損壞(其中有一些意想不到的字符)。
大約三四天前,我想到了有關信息檢查員的技術。我讀了this manual並在我的其他項目中實現了客戶端消息檢查器。實際上,我可以看到我的wcf客戶端發送的任何請求以及該請求的其他端服務響應。
我希望同樣容易的做另一方面的日誌記錄(例如,從客戶端獲得服務請求和服務器響應)。但我冷靜下來。 下面是詳細信息:
public class LogMessageBehavior : IEndpointBehavior
{
public LogMessageBehavior()
{ }
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{ }
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
throw new NotImplementedException();
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
LogMessageInspector inspector = new LogMessageInspector();
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
public class LogMessageBehaviorExtensionElement : BehaviorExtensionElement
{
public LogMessageBehaviorExtensionElement() { }
public override Type BehaviorType
{
get
{
return typeof(LogMessageBehavior);
}
}
protected override object CreateBehavior()
{
return new LogMessageBehavior();
}
}
public class LogMessageInspector : IDispatchMessageInspector
{
object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
throw new NotImplementedException();
}
void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
throw new NotImplementedException();
}
}
幾乎所有的代碼存根與NotImplementedException,但我設置在每個方法和屬性的斷點。此外,我會告訴他們如何受到打擊。
App.config
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="LogMessage" type="MyService.Extensions.LogMessageBehaviorExtensionElement, MyServiceApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="LogMessageEndpointBehavior">
<LogMessage />
</behavior>
</endpointBehaviors>
</behaviors>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="20000"/>
</diagnostics>
<!-- omitted for brewity -->
<services>
<service name="MyService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/"/>
</baseAddresses>
</host>
<endpoint address="MyServiceAddress" binding="basicHttpBinding" bindingConfiguration="MyService" contract="MyService" name="MyService" behaviorConfiguration="LogMessageEndpointBehavior">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="MyService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<!-- omitted for brewity -->
</basicHttpBinding>
</bindings>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\messages.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
這裏是如何服務安裝:
ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(Environment.bindAddress));
myserviceHost.Open();
Console.WriteLine(myserviceHost.BaseAddresses[0]);
Console.ReadLine();
服務類是沒有任何特殊的東西。
那麼,這個建築是如何工作的。如前所述,我在每種方法和屬性中都設置了斷點。後,我開始調試,我們得到了這個順序斷點命中:
1. public LogMessageBehaviorExtensionElement() { }
2. get { return typeof(LogMessageBehavior); }
3. get { return typeof(LogMessageBehavior); } (again)
4. get { return typeof(LogMessageBehavior); } (again)
5. get { return typeof(LogMessageBehavior); } (again)
OK,讓我們試着送東西到服務,看看它是如何反應。所以我發送一些請求(使用WSDL生成)來解決http://localhost:8733/
並獲得有效的響應。我爲此使用了SoapUI。 VS中沒有任何斷點活動!信息檢查員不工作。服務方法命中的斷點,它顯示該方法確實在沒有消息檢查器的情況下工作。
我也試着連接使用此代碼設置服務行爲(沒有相應的specifing行爲的app.config):
ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(Environment.bindAddress));
myserviceHost.Open();
foreach (ServiceEndpoint endpoint in myserviceHost.Description.Endpoints)
{
endpoint.Behaviors.Add(new LogMessageBehavior());
}
Console.WriteLine(myserviceHost.BaseAddresses[0]);
Console.ReadLine();
在這個選項中,我們得到的斷點的順序是:
1. public LogMessageBehavior() { }
就是這樣。也沒有任何督察的活動發送請求到服務。
那麼我怎樣才能得到它的工作?
您需要啓用並配置[消息記錄](http://msdn.microsoft.com/zh-cn/library/ms730064.aspx)。 –
@JohnSaunders我試過了。請看我的app.config。它寫入損壞的日誌,甚至我不知道如何從它獲取帶有時間戳的人類可讀信息。 – kseen
至於「腐敗」,你需要強制文件被刷新。停止服務將做到這一點。對於託管在IIS中的服務,我只是「觸摸」網頁。config - 在記事本中打開,鍵入空格,鍵入退格鍵,鍵入Control-S。服務會刷新日誌並重新啓動。 –