Freigeben über


Web Address Filters

Here is a basic service that defines a universal contract to program against for building a simple HTTP application. The service doesn't do anything, but you can ignore that in this example.

 [ServiceContract]
public interface IService
{
   [OperationContract(Action = "*", ReplyAction = "*")]
   Message Request(Message msg);
}

public class Service : IService
{
   public Message Request(Message msg)
   {
      Console.WriteLine("{0} {1}", WebOperationContext.Current.IncomingRequest.Method, msg.Headers.To);
      return null;
   }
}

You might expect to run this service in a straightforward hosting environment.

 ServiceHost host = new ServiceHost(typeof(Service), new Uri("https://localhost:8000/"));
host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
host.Open();
Console.ReadLine();
host.Close();

And, talk to it with the ordinarily convoluted client programming model.

 ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(new WebHttpBinding());
factory.Open();
IRequestChannel proxy = factory.CreateChannel(new EndpointAddress("https://localhost:8000/"));
using (new OperationContextScope((IContextChannel)proxy))
{
   Message request = Message.CreateMessage(MessageVersion.None, string.Empty, "data");
   request.Headers.To = new Uri("https://localhost:8000/resource");
   WebOperationContext.Current.OutgoingRequest.Method = "POST";
   proxy.Request(request);
}
using (new OperationContextScope((IContextChannel)proxy))
{
   Message request = Message.CreateMessage(MessageVersion.None, string.Empty);
   request.Headers.To = new Uri("https://localhost:8000/resource/1");
   WebOperationContext.Current.OutgoingRequest.Method = "GET";
   WebOperationContext.Current.OutgoingRequest.SuppressEntityBody = true;
   proxy.Request(request);
}

However, when you put these pieces together, it fails to work. The client turns out to be fine but there's a problem in the way that the service is hosted. More accurately, there's a problem with the interaction between the way the service is hosted and the way it's defined.

By specifying an address for hosting the application, we're claiming all of the messages that go to that address. We're also claiming all of the messages that go to suffixes of that address as long as someone else hasn't claimed them first. Unfortunately, the endpoint doesn't know what to do with these extra messages. It just ignores them.

What we want is for the endpoint to just take everything and let the service implementation decide what the addresses mean. We can do this by changing the service behavior.

The AddressFilterMode is a service behavior option that controls how the endpoint filters addresses. The default filter, Exact, only allows exact matches through. The filter we should be using instead, Prefix, uses a longest-prefix match to allow similar addresses through. The final filter, Any, just lets anything through.

We can fix this service with a service behavior that sets the AddressFilterMode to Prefix, but there's a better way to solve this problem instead that we'll look at next time.

Next time: Avoiding Address Filters

Comments

  • Anonymous
    July 29, 2008
    A few of the more noticeable changes in this week's site design might prompt some questions as to how