none
WCF Test Client and WebHttpBinding

    Question

  • I have hit a slight snag while creating a prototype that uses WCF. I'd really like some help as I'm trying to pitch WCF to the team for a fairly large project.

     

    I have a service that has multiple services configured. I have a http address configured in the base addresses element and have a couple of HTTP based endpoints configured using relative paths in Address property. They work great with the WCF Test Client that launches automatically for me when I start debugging.

     

    However, I have added the webHttpBinding as an endpoint and am having problems with the client configuration that is being generating. Most notably, no matter what I do it will not put in the url for the webHttpBinding endpoint. Instead It has something similiar to this (For some reason it gets turned into a custom binding as well):

     

    <endpoint name="webEndpoint" contract="MyContract" bindingConfiguration="webEndpoint" binding="customBinding" />

     

    All of the other end poings are given an address like the following (Notice how the address attribute is included:

     

    <endpoint address="http://localhost:8877/SOAP" binding="basicHttpBinding" bindingConfiguration="soapEndpoint" contract="MyContract" name="soapEndpoint" /></< P>

     

    Any tips?

    Wednesday, February 20, 2008 8:22 AM

Answers

  • This is a limitation of the web programming model itself. Unlike SOAP endpoints (i.e., those with BasicHttpBinding, WSHttpBinding, etc) which have a way to expose metadata about itself (WSDL or Mex) with information about all the operations / parameters in the endpoint, there's currently no standard way to expose metadata for a non-SOAP endpoint - and that's exactly what the webHttpBinding-based endpoints are. In short, the WCF Test Client won't be useful for web-based endpoints. If some standard for representing web-style endpoints emerges when WCF ships its next version, we'll likely update the test client to support it, but for now there's none widely adopted.

     

    One alternative you can try (although definitely not as simple / handy) is to create the test client yourself in code using the ChannelFactory<T> class (using the same contract / binding / behavior used in the service (see example below). You can then use some network capture/replay tool such as Fiddler (www.fiddlertool.com) to send additional requests to the service.

     

    public class Post2874275

    {

        [ServiceContract]

        public interface ITest

        {

            [OperationContract]

            [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]

            int Add(int x, int y);

            [OperationContract]

            [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]

            int Subtract(int x, int y);

        }

        public class Service : ITest

        {

            public int Add(int x, int y)

            {

                return x + y;

            }

            public int Subtract(int x, int y)

            {

                return x - y;

            }

        }

        public static void Test()

        {

            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";

            ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));

            host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());

            host.Open();

            Console.WriteLine("Host opened");

     

            ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new WebHttpBinding(), new EndpointAddress(baseAddress));

            factory.Endpoint.Behaviors.Add(new WebHttpBehavior());

            ITest proxy = factory.CreateChannel();

     

            int x = 752;

            int y = 321;

            Console.WriteLine(proxy.Add(x, y));

            Console.WriteLine(proxy.Subtract(x, y));

     

            ((IClientChannel)proxy).Close();

            factory.Close();

            Console.Write("Press ENTER to close the service");

            Console.ReadLine();

            host.Close();

        }

    }

    Wednesday, February 20, 2008 3:13 PM

All replies

  • This is a limitation of the web programming model itself. Unlike SOAP endpoints (i.e., those with BasicHttpBinding, WSHttpBinding, etc) which have a way to expose metadata about itself (WSDL or Mex) with information about all the operations / parameters in the endpoint, there's currently no standard way to expose metadata for a non-SOAP endpoint - and that's exactly what the webHttpBinding-based endpoints are. In short, the WCF Test Client won't be useful for web-based endpoints. If some standard for representing web-style endpoints emerges when WCF ships its next version, we'll likely update the test client to support it, but for now there's none widely adopted.

     

    One alternative you can try (although definitely not as simple / handy) is to create the test client yourself in code using the ChannelFactory<T> class (using the same contract / binding / behavior used in the service (see example below). You can then use some network capture/replay tool such as Fiddler (www.fiddlertool.com) to send additional requests to the service.

     

    public class Post2874275

    {

        [ServiceContract]

        public interface ITest

        {

            [OperationContract]

            [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]

            int Add(int x, int y);

            [OperationContract]

            [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]

            int Subtract(int x, int y);

        }

        public class Service : ITest

        {

            public int Add(int x, int y)

            {

                return x + y;

            }

            public int Subtract(int x, int y)

            {

                return x - y;

            }

        }

        public static void Test()

        {

            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";

            ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));

            host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());

            host.Open();

            Console.WriteLine("Host opened");

     

            ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new WebHttpBinding(), new EndpointAddress(baseAddress));

            factory.Endpoint.Behaviors.Add(new WebHttpBehavior());

            ITest proxy = factory.CreateChannel();

     

            int x = 752;

            int y = 321;

            Console.WriteLine(proxy.Add(x, y));

            Console.WriteLine(proxy.Subtract(x, y));

     

            ((IClientChannel)proxy).Close();

            factory.Close();

            Console.Write("Press ENTER to close the service");

            Console.ReadLine();

            host.Close();

        }

    }

    Wednesday, February 20, 2008 3:13 PM
  • You should try out SOA Cleaner, it supports WebHttpBinding testing. It has a free version, can be downloaded at: http://xyrow.com.
    • Proposed as answer by Clangon Thursday, September 17, 2009 7:02 AM
    Wednesday, September 16, 2009 7:20 AM