2012-11-28 63 views
1

最近,我正在探索一些方法來記錄我的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() { } 

就是這樣。也沒有任何督察的活動發送請求到服務。

那麼我怎樣才能得到它的工作?

+1

您需要啓用並配置[消息記錄](http://msdn.microsoft.com/zh-cn/library/ms730064.aspx)。 –

+0

@JohnSaunders我試過了。請看我的app.config。它寫入損壞的日誌,甚至我不知道如何從它獲取帶有時間戳的人類可讀信息。 – kseen

+0

至於「腐敗」,你需要強制文件被刷新。停止服務將做到這一點。對於託管在IIS中的服務,我只是「觸摸」網頁。config - 在記事本中打開,鍵入空格,鍵入退格鍵,鍵入Control-S。服務會刷新日誌並重新啓動。 –

回答

0

嘗試添加行爲後打開主機。它應該工作正常。

ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(Environment.bindAddress)); 

foreach (ServiceEndpoint endpoint in myserviceHost.Description.Endpoints) 
{ 
    endpoint.Behaviors.Add(new LogMessageBehavior()); 
} 

myserviceHost.Open(); 

Console.WriteLine(myserviceHost.BaseAddresses[0]); 
Console.ReadLine();