- Article
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
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);}
<ServiceContract()> _Public Interface IService <OperationContract()> _ <WebGet()> _ Function EchoWithGet(ByVal s As String) As String <OperationContract()> _ <WebInvoke()> _ Function EchoWithPost(ByVal s As String) As StringEnd Interface
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.
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; }}
Public Class Service Implements IService Public Function EchoWithGet(ByVal s As String) As String Implements IService.EchoWithGet Return "You said " + s End Function Public Function EchoWithPost(ByVal s As String) As String Implements IService.EchoWithPost Return "You said " + s End FunctionEnd Class
To host the service
Create a ServiceHost object, as shown in the following code:
ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
Dim host As New ServiceHost(GetType(Service), New Uri("http://localhost:8000"))
Add a ServiceEndpoint with BasicHttpBinding for the SOAP endpoint, as shown in the following code:
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
host.AddServiceEndpoint(GetType(IService), New BasicHttpBinding(), "Soap")
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());
Dim endpoint As ServiceEndpointendpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "Web")endpoint.Behaviors.Add(New WebHttpBehavior())
Call
Open()
on a ServiceHost instance to open the service host, as shown in the following code:host.Open();
host.Open()
To call service operations mapped to GET in a browser
- In a web browser, browse to "
http://localhost:8000/Web/EchoWithGet?s=Hello, world!
". 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
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")))
Using wcf As New WebChannelFactory(Of IService)(New Uri("http://localhost:8000/Web"))
Note
Close()
is automatically called on the channel at the end of the using
block.
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);
Dim channel As IService = wcf.CreateChannel()Dim s As StringConsole.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
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"))
Using scf As New ChannelFactory(Of IService)(New BasicHttpBinding(), "http://localhost:8000/Soap")
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);
Dim channel As IService = scf.CreateChannel()Dim s As StringConsole.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
Close the service host, as shown in the following code.
host.Close();
host.Close()
Example
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(); } } }}
Imports System.Collections.GenericImports System.ServiceModelImports System.ServiceModel.DescriptionImports System.ServiceModel.WebImports System.Text<ServiceContract()> _Public Interface IService <OperationContract()> _ <WebGet()> _ Function EchoWithGet(ByVal s As String) As String <OperationContract()> _ <WebInvoke()> _ Function EchoWithPost(ByVal s As String) As StringEnd InterfacePublic Class Service Implements IService Public Function EchoWithGet(ByVal s As String) As String Implements IService.EchoWithGet Return "You said " + s End Function Public Function EchoWithPost(ByVal s As String) As String Implements IService.EchoWithPost Return "You said " + s End FunctionEnd ClassModule Program Sub Main() Dim host As New ServiceHost(GetType(Service), New Uri("http://localhost:8000")) host.AddServiceEndpoint(GetType(IService), New BasicHttpBinding(), "Soap") Dim endpoint As ServiceEndpoint endpoint = host.AddServiceEndpoint(GetType(IService), New WebHttpBinding(), "Web") endpoint.Behaviors.Add(New WebHttpBehavior()) Try host.Open() Using wcf As New WebChannelFactory(Of IService)(New Uri("http://localhost:8000/Web")) Dim channel As IService = wcf.CreateChannel() Dim s As String 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("") End Using Using scf As New ChannelFactory(Of IService)(New BasicHttpBinding(), "http://localhost:8000/Soap") Dim channel As IService = scf.CreateChannel() Dim s As String 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("") End Using Console.WriteLine("Press <Enter> to terminate") Console.ReadLine() host.Close() Catch cex As CommunicationException Console.WriteLine("An exception occurred: {0}", cex.Message) host.Abort() End Try End SubEnd Module
Compiling the code
When compiling Service.cs, reference System.ServiceModel.dll and System.ServiceModel.Web.dll.
See also
- WebHttpBinding
- WebGetAttribute
- WebInvokeAttribute
- WebServiceHost
- ChannelFactory
- WebHttpBehavior
- WCF Web HTTP Programming Model