locked
programmatically adding message inspectors RRS feed

  • Question

  •  public class MyMessageInspector : IDispatchMessageInspector
    
     {
    
      public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    
      {
    
       //dosomething   
    
       return null;
    
      }
    
    
    
      public void BeforeSendReply(ref Message reply, object correlationState)
    
      {   
    
      }
    
     }
    
    
    
    ----------------------------------------------------------------------
    
     private void Host()
    
      {
    
       Uri baseaddress = new Uri("net.tcp://localhost:8090/");
    
       MyService service = new MyService();
    
     ServiceHost serviceHost = new ServiceHost(service ,baseaddress);
    
       Binding tcpbinding = new NetTcpBinding();   
    
       ServiceEndpoint endPoint = serviceHost.AddServiceEndpoint(typeof(IMyService), tcpbinding, "ServiceName");
    
       
    
       SecurityServiceBehaviour serviceBehaviour = new SecurityServiceBehaviour();
    
       serviceBehaviour.ApplyDispatchBehavior(serviceHost.Description, serviceHost);
    
       //endPoint.Behaviors.Add();
    
       serviceHost.Open();
    
       
    
      }
    
    
    
      private class SecurityServiceBehaviour : IServiceBehavior
    
      {
    
       public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    
       {
    
        
    
       }
    
    
    
       public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    
       {
    
        return;
    
       }
    
    
    
       public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    
       {
    
        foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers)
    
        {
    
         foreach (EndpointDispatcher epDisp in chDisp.Endpoints)
    
         {
    
          epDisp.DispatchRuntime.MessageInspectors.Add(new WindowsCredentialsMessageInspector());      
    
         }
    
        }
    
    
    
       }
    
      }

    In ApplyDispatchBehavior serviceHostBase.ChannelDispatchers is returnign empty collection so is not adding the message interceptor to endpoint . Did I miss anything ?


    ajit
    Thursday, January 13, 2011 5:57 PM

Answers

  • The channel dispatchers will only be populated when the service host is being opened. You need to add the service behavior to the list in the service description, and let WCF call it when the internal data structures have been properly set, like in the example below:

      public class Post_ef5f9f03_9312_468e_ae8d_a5b1ac8adaad
      {
        [ServiceContract]
        public interface ITest
        {
          [OperationContract]
          string Echo(string text);
        }
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        public class Service : ITest
        {
          public string Echo(string text)
          {
            return text;
          }
        }
        public class MyMessageInspector : IDispatchMessageInspector
        {
          public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
          {
            Console.WriteLine("Request:");
            Console.WriteLine(request);
            return null;
          }
    
          public void BeforeSendReply(ref Message reply, object correlationState)
          {
            Console.WriteLine("Reply:");
            Console.WriteLine(reply);
          }
        }
        public class MyServiceBehavior : IServiceBehavior
        {
          public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
          {
          }
    
          public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
          {
            foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers)
            {
              foreach (EndpointDispatcher epDisp in chDisp.Endpoints)
              {
                epDisp.DispatchRuntime.MessageInspectors.Add(new MyMessageInspector());
              }
            }
          }
    
          public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
          {
          }
        }
        public static void Test()
        {
          string baseAddress = "net.tcp://" + Environment.MachineName + ":8000/Service";
          Service service = new Service();
          ServiceHost host = new ServiceHost(service, new Uri(baseAddress));
          host.AddServiceEndpoint(typeof(ITest), new NetTcpBinding(), "");
          host.Description.Behaviors.Add(new MyServiceBehavior());
          host.Open();
          Console.WriteLine("Host opened");
    
          ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new NetTcpBinding(), new EndpointAddress(baseAddress));
          ITest proxy = factory.CreateChannel();
          Console.WriteLine(proxy.Echo("Hello"));
    
          ((IClientChannel)proxy).Close();
          factory.Close();
    
          Console.Write("Press ENTER to close the host");
          Console.ReadLine();
          host.Close();
        }
      }
    
    
    • Marked as answer by chintapali Thursday, January 13, 2011 7:44 PM
    Thursday, January 13, 2011 7:23 PM

All replies

  • The channel dispatchers will only be populated when the service host is being opened. You need to add the service behavior to the list in the service description, and let WCF call it when the internal data structures have been properly set, like in the example below:

      public class Post_ef5f9f03_9312_468e_ae8d_a5b1ac8adaad
      {
        [ServiceContract]
        public interface ITest
        {
          [OperationContract]
          string Echo(string text);
        }
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        public class Service : ITest
        {
          public string Echo(string text)
          {
            return text;
          }
        }
        public class MyMessageInspector : IDispatchMessageInspector
        {
          public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
          {
            Console.WriteLine("Request:");
            Console.WriteLine(request);
            return null;
          }
    
          public void BeforeSendReply(ref Message reply, object correlationState)
          {
            Console.WriteLine("Reply:");
            Console.WriteLine(reply);
          }
        }
        public class MyServiceBehavior : IServiceBehavior
        {
          public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
          {
          }
    
          public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
          {
            foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers)
            {
              foreach (EndpointDispatcher epDisp in chDisp.Endpoints)
              {
                epDisp.DispatchRuntime.MessageInspectors.Add(new MyMessageInspector());
              }
            }
          }
    
          public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
          {
          }
        }
        public static void Test()
        {
          string baseAddress = "net.tcp://" + Environment.MachineName + ":8000/Service";
          Service service = new Service();
          ServiceHost host = new ServiceHost(service, new Uri(baseAddress));
          host.AddServiceEndpoint(typeof(ITest), new NetTcpBinding(), "");
          host.Description.Behaviors.Add(new MyServiceBehavior());
          host.Open();
          Console.WriteLine("Host opened");
    
          ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new NetTcpBinding(), new EndpointAddress(baseAddress));
          ITest proxy = factory.CreateChannel();
          Console.WriteLine(proxy.Echo("Hello"));
    
          ((IClientChannel)proxy).Close();
          factory.Close();
    
          Console.Write("Press ENTER to close the host");
          Console.ReadLine();
          host.Close();
        }
      }
    
    
    • Marked as answer by chintapali Thursday, January 13, 2011 7:44 PM
    Thursday, January 13, 2011 7:23 PM
  • How would this be done without a coded host, say, in hosting in IIS?

    WFB

    Wednesday, May 23, 2012 7:05 PM