none
WCF routing filters RRS feed

  • Question

  • Hi,

    Looking at the routing service and I Wonder if there isn't a filter out-of-the-box that filters on the originator/sender? That is, I want to route messages from customerX to serviceX and messages from customerY to serviceY. Message might be the same type.

    Do I have to create my own filter for this? Any pointers/links on how to do this?

    Thanks.

    --
    Werner


    Tuesday, November 5, 2013 10:58 AM

Answers

  • Hi Werner,

    For WCF routering, its built-in filters need us to specify which part of the message (normally the headers or content data) will it use for determing routing target. You can take a look at the routing samples in the WCF .NET samples for more ideas:

    #Advanced Filters
    http://msdn.microsoft.com/en-us/library/ee667249(v=vs.110).aspx

    #WCF Content-based Routing Sample A
    http://code.msdn.microsoft.com/WCF-Content-based-Routing-71c4a2cc


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, November 7, 2013 7:45 AM
    Moderator
  • Hi Werner,

    Yes, you have to create a custom message filter to solve your case. The following code snippet shows an example of the custom message filter with wildcard expression for matching a client IP:Port address:

    public class ClientAddressMessageFilter : MessageFilter
    {
      public string WildcardExpression { get; set; }
    
      public ClientAddressMessageFilter(string wildcardExpression)
      {
        this.WildcardExpression = wildcardExpression;
      }
    
      public override bool Match(System.ServiceModel.Channels.Message message)
      {
         return this.InnerMatch(message);
      }
    
      public override bool Match(System.ServiceModel.Channels.MessageBuffer buffer)
      {
        bool retVal = false;
    
        if (buffer == null)
          throw new ArgumentNullException("buffer");
    
        var message = buffer.CreateMessage();
        try
        {
          retVal = this.InnerMatch(message);
        }
        finally
        {
          message.Close();
        }
        return retVal;
      }
    
      private bool InnerMatch(System.ServiceModel.Channels.Message message)
      {
         RemoteEndpointMessageProperty repProperty = message.Properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
         if (repProperty == null)
            return false;
    
         string clientAddress = repProperty.Address + ":" + repProperty.Port;
    
         string pattern = "^" + Regex.Escape(this.WildcardExpression).Replace(@"\*", ".*").Replace(@"\?", ".") + "$";
         
         bool isMatch = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline).IsMatch(clientAddress);
    
         Trace.TraceInformation("MessageFilter: {0} is {1} for pattern {2}", clientAddress, Convert.ToString(isMatch).ToUpper(), this.WildcardExpression);
    
         return isMatch;
      }
    }

    Thanks

    Roman


    Roman Kiss, MVP Microsoft Integration: Development

    • Marked as answer by Werner Clausen Monday, November 11, 2013 7:32 AM
    Saturday, November 9, 2013 1:44 PM

All replies

  • Hi Werner,

    For WCF routering, its built-in filters need us to specify which part of the message (normally the headers or content data) will it use for determing routing target. You can take a look at the routing samples in the WCF .NET samples for more ideas:

    #Advanced Filters
    http://msdn.microsoft.com/en-us/library/ee667249(v=vs.110).aspx

    #WCF Content-based Routing Sample A
    http://code.msdn.microsoft.com/WCF-Content-based-Routing-71c4a2cc


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, November 7, 2013 7:45 AM
    Moderator
  • Thanks Steven, but I dont quite follow. Are you really saying that it isn't possible to route messages based on origin/sender?

    -- 
    Werner


    Thursday, November 7, 2013 11:41 AM
  • Bump - no one knows? Isn't it possible to route messages based on origin/sender?
    Friday, November 8, 2013 2:17 PM
  • Hi Werner,

    Yes, you have to create a custom message filter to solve your case. The following code snippet shows an example of the custom message filter with wildcard expression for matching a client IP:Port address:

    public class ClientAddressMessageFilter : MessageFilter
    {
      public string WildcardExpression { get; set; }
    
      public ClientAddressMessageFilter(string wildcardExpression)
      {
        this.WildcardExpression = wildcardExpression;
      }
    
      public override bool Match(System.ServiceModel.Channels.Message message)
      {
         return this.InnerMatch(message);
      }
    
      public override bool Match(System.ServiceModel.Channels.MessageBuffer buffer)
      {
        bool retVal = false;
    
        if (buffer == null)
          throw new ArgumentNullException("buffer");
    
        var message = buffer.CreateMessage();
        try
        {
          retVal = this.InnerMatch(message);
        }
        finally
        {
          message.Close();
        }
        return retVal;
      }
    
      private bool InnerMatch(System.ServiceModel.Channels.Message message)
      {
         RemoteEndpointMessageProperty repProperty = message.Properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
         if (repProperty == null)
            return false;
    
         string clientAddress = repProperty.Address + ":" + repProperty.Port;
    
         string pattern = "^" + Regex.Escape(this.WildcardExpression).Replace(@"\*", ".*").Replace(@"\?", ".") + "$";
         
         bool isMatch = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline).IsMatch(clientAddress);
    
         Trace.TraceInformation("MessageFilter: {0} is {1} for pattern {2}", clientAddress, Convert.ToString(isMatch).ToUpper(), this.WildcardExpression);
    
         return isMatch;
      }
    }

    Thanks

    Roman


    Roman Kiss, MVP Microsoft Integration: Development

    • Marked as answer by Werner Clausen Monday, November 11, 2013 7:32 AM
    Saturday, November 9, 2013 1:44 PM
  • That's excellent, thanks Roman!
    Monday, November 11, 2013 7:32 AM