none
WCF and extensibility

    Question

  • Hi

    Is it possible to run a method before or after each call is made to a WCF method?

    If so, is it possible to set a context that is available inside the WCF method?

    Thanks

    Thursday, August 19, 2010 3:59 PM

Answers

  • Yes, you can use an IDispatchMessageInspector for that. And you can use the message properties to pass information between the inspector and the method (properties aren't reflected in the message that goes across the wire). The code below shows an example of it.

      public class Post_bc07fa75_84d7_4fd2_b56a_9192372aefb1
      {
        [ServiceContract]
        public interface ITest
        {
          [OperationContract]
          int Add(int x, int y);
        }
        public class Service : ITest
        {
          public int Add(int x, int y)
          {
            object propValue;
            if (OperationContext.Current.IncomingMessageProperties.TryGetValue(MyInspector.MyPropertyName, out propValue))
            {
              Console.WriteLine("AfterReceiveRequest set the following value: {0}", propValue);
            }
    
            OperationContext.Current.OutgoingMessageProperties.Add(MyInspector.MyPropertyName, "Set by the method to be used by the inspector");
            return x + y;
          }
        }
        static Binding GetBinding()
        {
          BasicHttpBinding result = new BasicHttpBinding();
          return result;
        }
        public class MyInspector : IDispatchMessageInspector, IEndpointBehavior
        {
          internal const string MyPropertyName = "ThePropertyName";
          public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
          {
          }
    
          public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
          {
          }
    
          public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
          {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
          }
    
          public void Validate(ServiceEndpoint endpoint)
          {
          }
    
          public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
          {
            request.Properties.Add(MyPropertyName, "This is available for the method");
            return null;
          }
    
          public void BeforeSendReply(ref Message reply, object correlationState)
          {
            object propValue;
            if (reply.Properties.TryGetValue(MyPropertyName, out propValue))
            {
              Console.WriteLine("Method set this value: {0}", propValue);
            }
          }
        }
        public static void Test()
        {
          string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
          ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
          ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
          endpoint.Behaviors.Add(new MyInspector());
          host.Open();
          Console.WriteLine("Host opened");
    
          ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
          ITest proxy = factory.CreateChannel();
    
          Console.WriteLine(proxy.Add(3, 5));
    
          ((IClientChannel)proxy).Close();
          factory.Close();
    
          Console.Write("Press ENTER to close the host");
          Console.ReadLine();
          host.Close();
        }
      }
    
    
    • Proposed as answer by Carlos Figueira Friday, August 20, 2010 6:44 PM
    • Marked as answer by bkejser_ Sunday, August 22, 2010 2:00 PM
    Thursday, August 19, 2010 4:20 PM