Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

How to: Expose a Contract to SOAP and Web Clients

 

By default, Windows Communication Foundation (WCF) makes endpoints available only to SOAP clients. In How to: Create a Basic WCF Web HTTP Service, an endpoint is made available to non-SOAP clients. There may be times when you want to make the same contract available both ways, as a Web endpoint and as a SOAP endpoint. This topic shows an example of how to do this.

To define the service contract

  1. Define a service contract using an interface marked with the ServiceContractAttribute, WebInvokeAttribute and the WebGetAttribute attributes, as shown in the following code.

        [ServiceContract]
        public interface IService
        {
            [OperationContract]
            [WebGet]
            string EchoWithGet(string s);
    
            [OperationContract]
            [WebInvoke]
            string EchoWithPost(string s);
        }
    

    System_CAPS_ICON_note.jpg Note

    By default WebInvokeAttribute maps POST calls to the operation. You can, however, specify the method to map to the operation by specifying a "method=" parameter. WebGetAttribute does not have a "method=" parameter and only maps GET calls to the service operation.

  2. Implement the service contract, as shown in the following code.

        public class Service : IService
        {
            public string EchoWithGet(string s)
            {
                return "You said " + s;
            }
    
            public string EchoWithPost(string s)
            {
                return "You said " + s;
            }
        }
    

To host the service

  1. Create a ServiceHost object, as shown in the following code.

                ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
    

  2. Add a ServiceEndpoint with BasicHttpBinding for the SOAP endpoint, as shown in the following code.

                host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
    

  3. Add a ServiceEndpoint with WebHttpBinding for the non-SOAP endpoint and add the WebHttpBehavior to the endpoint, as shown in the following code.

                ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "Web");
                endpoint.Behaviors.Add(new WebHttpBehavior());
    

  4. Call Open() on a ServiceHost instance to open the service host, as shown in the following code.

                    host.Open();
    

To call service operations mapped to GET in Internet Explorer

  1. Open Internet Explorer and type "http://localhost:8000/Web/EchoWithGet?s=Hello, world!" and press ENTER. The URL contains the base address of the service ("http://localhost:8000/"), the relative address of the endpoint (""), the service operation to call ("EchoWithGet"), and a question mark followed by a list of named parameters separated by an ampersand (&).

To call service operations on the Web endpoint in code

  1. Create an instance of WebChannelFactory<TChannel> within a using block, as shown in the following code.

                    using (WebChannelFactory<IService> wcf = new WebChannelFactory<IService>(new Uri("http://localhost:8000/Web")))
    

System_CAPS_ICON_note.jpg Note

Close() is automatically called on the channel at the end of the using block.

  1. Create the channel and call the service, as shown in the following code.

                        IService channel = wcf.CreateChannel();
    
                        string s;
    
                        Console.WriteLine("Calling EchoWithGet by HTTP GET: ");
                        s = channel.EchoWithGet("Hello, world");
                        Console.WriteLine("   Output: {0}", s);
    
                        Console.WriteLine("");
                        Console.WriteLine("This can also be accomplished by navigating to");
                        Console.WriteLine("http://localhost:8000/Web/EchoWithGet?s=Hello, world!");
                        Console.WriteLine("in a web browser while this sample is running.");
    
                        Console.WriteLine("");
    
                        Console.WriteLine("Calling EchoWithPost by HTTP POST: ");
                        s = channel.EchoWithPost("Hello, world");
                        Console.WriteLine("   Output: {0}", s);
    

To call service operations on the SOAP endpoint

  1. Create an instance of ChannelFactory within a using block, as shown in the following code.

                    using (ChannelFactory<IService> scf = new ChannelFactory<IService>(new BasicHttpBinding(), "http://localhost:8000/Soap"))
    

  2. Create the channel and call the service, as shown in the following code.

                        IService channel = scf.CreateChannel();
    
                        string s;
    
                        Console.WriteLine("Calling EchoWithGet on SOAP endpoint: ");
                        s = channel.EchoWithGet("Hello, world");
                        Console.WriteLine("   Output: {0}", s);
    
                        Console.WriteLine("");
    
                        Console.WriteLine("Calling EchoWithPost on SOAP endpoint: ");
                        s = channel.EchoWithPost("Hello, world");
                        Console.WriteLine("   Output: {0}", s);
    

To close the service host

  1. Close the service host, as shown in the following code.

                    host.Close();
    

The following is the full code listing for this topic.

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;

namespace Microsoft.ServiceModel.Samples.BasicWebProgramming
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebGet]
        string EchoWithGet(string s);

        [OperationContract]
        [WebInvoke]
        string EchoWithPost(string s);
    }

    public class Service : IService
    {
        public string EchoWithGet(string s)
        {
            return "You said " + s;
        }

        public string EchoWithPost(string s)
        {
            return "You said " + s;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
            host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
            ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "Web");
            endpoint.Behaviors.Add(new WebHttpBehavior());
            
            try
            {
                host.Open();

                using (WebChannelFactory<IService> wcf = new WebChannelFactory<IService>(new Uri("http://localhost:8000/Web")))
                {
                    IService channel = wcf.CreateChannel();

                    string s;

                    Console.WriteLine("Calling EchoWithGet by HTTP GET: ");
                    s = channel.EchoWithGet("Hello, world");
                    Console.WriteLine("   Output: {0}", s);

                    Console.WriteLine("");
                    Console.WriteLine("This can also be accomplished by navigating to");
                    Console.WriteLine("http://localhost:8000/Web/EchoWithGet?s=Hello, world!");
                    Console.WriteLine("in a web browser while this sample is running.");

                    Console.WriteLine("");

                    Console.WriteLine("Calling EchoWithPost by HTTP POST: ");
                    s = channel.EchoWithPost("Hello, world");
                    Console.WriteLine("   Output: {0}", s);
                    Console.WriteLine("");
                }
                using (ChannelFactory<IService> scf = new ChannelFactory<IService>(new BasicHttpBinding(), "http://localhost:8000/Soap"))
                {
                    IService channel = scf.CreateChannel();

                    string s;

                    Console.WriteLine("Calling EchoWithGet on SOAP endpoint: ");
                    s = channel.EchoWithGet("Hello, world");
                    Console.WriteLine("   Output: {0}", s);

                    Console.WriteLine("");

                    Console.WriteLine("Calling EchoWithPost on SOAP endpoint: ");
                    s = channel.EchoWithPost("Hello, world");
                    Console.WriteLine("   Output: {0}", s);
                    Console.WriteLine("");
                }


                Console.WriteLine("Press [Enter] to terminate");
                Console.ReadLine();
                host.Close();
            }
            catch (CommunicationException cex)
            {
                Console.WriteLine("An exception occurred: {0}", cex.Message);
                host.Abort();
            }
        }
    }
}

When compiling Service.cs, reference System.ServiceModel.dll and System.ServiceModel.Web.dll.

WebHttpBinding
WebGetAttribute
WebInvokeAttribute
WebServiceHost
ChannelFactory
WebHttpBehavior
WCF Web HTTP Programming Model

Show: