WCF消息检查器不起作用

时间:2012-11-28 03:41:53

标签: c# .net wcf wcf-extensions

最近,我正在探索一些方法来记录我的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)

好的,让我们尝试发送一些服务,看看它是如何反应的。所以我发送一些请求(使用WSDL生成)来解决http://localhost:8733/并获得有效响应。我使用了SoapUI。并且VS中没有任何断点活动!消息检查员无法正常工作。关于服务方法命中的断点,它表明该方法确实在没有消息检查器的情况下工作。

此外,我尝试使用此代码附加行为来设置服务(因此没有在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 个答案:

答案 0 :(得分: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();