WCF December CTP: You cannot repurpose proxies once the channel has been built.


Bummer? Sorta, but not really.


To the quick: Once the channel has been created for a proxy, any subsequent invocations on that proxy use the original channel. This is true even if, as I did in this sample here (http://blogs.msdn.com/ralph.squillace/archive/2005/10/18/482536.aspx), you change the address or binding before you use it again. Here's what I did in the sample:


    foreach(ServiceEndpoint point in endpoints)
    {
      if (point != null)
      {
        newEndpoint = point;
        proxy.Endpoint.Address = newEndpoint.Address;
        proxy.Endpoint.Binding = newEndpoint.Binding;
        Console.WriteLine(
          proxy.HelloFirst("Client used the "
          + point.Address.ToString()
          + " address.")
        );
      }
    }


See, you'd think this works. I have a proxy, and I fish out and modify the binding and the address of it. Does it work? Yes. It works. Does it work the way you think it does? NO. It does not.


Rules:



  1. You cannot modify a proxy created from ChannelFactory.CreateChannel(). The underlying channel has been created and validated; it cannot now be changed.

  2. You cannot modify a ClientBase<T> proxy once an service operation has been called. The underlying channel is created when the first call is made. Therefore, you CAN modify such a proxy after it's been created but prior to the first call.

I meant to correct the code but Christian Weyer got to me first and geez, now he's provoked me. So here's the code that demonstrates that it doesn't work the way you think, provided to me by the kind developer who pointed out my mistake.


using System;
using System.ServiceModel;


namespace Server
{
    [ServiceContract]
    public interface IMyContract
    {
        [OperationContract]
        string echo(string s);
    }


    public class MyService : IMyContract
    {
        public string echo(string s)
        {
            Console.WriteLine("Proxy thinks it is talking to {0}", s);
            Console.WriteLine("Proxy is actually talking to {0}", OperationContext.Current.IncomingMessageProperties.Via);
            return s;
        }
    }
}


public class Repro
{
    public static void Main()
    {
        Uri address = new Uri("
http://localhost:8004/Service");
        Uri address2 = new Uri("
http://localhost:8004/Service/other");
        Binding binding = new BasicHttpBinding();


        ServiceHost service = new ServiceHost(typeof(Server.MyService), address);
        using (service)
        {
            service.AddServiceEndpoint(typeof(Server.IMyContract), binding, address);
            service.AddServiceEndpoint(typeof(Server.IMyContract), binding, address2);
            service.Open();


            Console.WriteLine("Service open at {0} - press a key to continue", address);
            Console.ReadKey();


            MyContractProxy proxy = new MyContractProxy("IMyContract");
            proxy.Endpoint.Address = new EndpointAddress(address);
            proxy.Endpoint.Binding = binding;
            proxy.echo(address.ToString());


            proxy.Endpoint.Address = new EndpointAddress(address2);
            proxy.Endpoint.Binding = binding;
            proxy.echo(address2.ToString());


            Console.WriteLine("Done, press a key");
            Console.ReadKey();


            /*
             * Results in:
  Service open at
http://localhost:8004/Service - press a key to continue
  Proxy thinks it is talking to
http://localhost:8004/Service
  Proxy is actually talking to http://localhost:8004/Service
  Proxy thinks it is talking to http://localhost:8004/Service/other
  Proxy is actually talking to http://localhost:8004/Service
  Done, press a key


             */
          }
    }
}


So THERE, Christian. 🙂 The problem with this, as Christian says, is that because there's no exception, you're left in ignorance that your application is now misbehaving. Bad, bad. Well, not to fear. We plan to throw an exception in the future. 🙂


Hope this helps!!! Next, some random custom header throwing. Just for fun, you realize.


 


Skip to main content