In this post I will show you how to create a WCF Service with both SOAP and REST paradigms. For purpose of this post, I am going to create a
Calculator Service with the following characterstics
- Serivice will have both SOAP and REST enabled
- REST Service will have JOSN Message format
In the later part of the post, I will show you a
way to consume both types of Service in a manged (console) client.
Idea
- There would be two ServiceContract . One ServiceContract for SOAP and one for REST.
- There would be one Service Defintion file
- There would be two bindings enabled on the service. One binding corrosponds to SOAP and other to REST
- For SOAP , basicHttpBinding would be used and for REST webHttpBinding would be used
- Both SOAP and REST will have same base address
Note : I have created a different Service Contract for REST and SOAP. However
you can have it on same ServiceContract also.
Create Service
Let us create two service contracts . One for SOAP and one for the REST Service. I
have created a Service Contract IService1 for SOAP as below,
IService1.cs
[ServiceContract]
public interface
IService1
{
[OperationContract]
int Add(int
Number1, int Number2);
[OperationContract]
int Sub(int
Number1, int Number2);
[OperationContract]
int Mul(int
Number1, int Number2);
[OperationContract]
int Div(int
Number1, int Number2);
}
Next I have created a Service Contract IService2 for REST as below,
IService2.cs
[ServiceContract]
public interface
IService2
{
[OperationContract]
[WebGet(UriTemplate="/Add/{Number1}/{Number2}",RequestFormat=WebMessageFormat.Json,
ResponseFormat =
WebMessageFormat.Json
)]
int AddRest(string
Number1, string Number2);
[OperationContract]
[WebGet(UriTemplate="/Sub/{Number1}/{Number2}",RequestFormat=WebMessageFormat.Json,
ResponseFormat =
WebMessageFormat.Json
)]
int SubRest(string
Number1, string Number2);
[OperationContract]
[WebGet(UriTemplate="/Mul/{Number1}/{Number2}",RequestFormat=WebMessageFormat.Json,
ResponseFormat =
WebMessageFormat.Json
)]
int MulRest(string
Number1, string Number2);
[OperationContract]
[WebGet(UriTemplate="/Div/{Number1}/{Number2}",RequestFormat=WebMessageFormat.Json,
ResponseFormat =
WebMessageFormat.Json
)]
int DivRest(string
Number1, string Number2);
}
In the above service I am explictly setting the message format to JSON. So the above service
is a JSON enabled REST Service. Since REST based service does not take input
parameter but string type so input parameters to functions is of string type.
Implementing Service
The service is implemented in a simple way. All the operation contracts from the
service are performing trivial calculating functions.
Service1.svc.cs
using
System;
namespace
MultipleBindingWCF
{
public class
Service1 : IService1,IService2
{
public int Add(int
Number1, int Number2)
{
return Number1 + Number2;
}
public int Sub(int
Number1, int Number2)
{
return Number1 - Number2;
}
public int
Mul(int Number1, int
Number2)
{
return Number1 * Number2;
}
public int Div(int
Number1, int Number2)
{
return Number1 / Number2;
}
public int
AddRest(string Number1,
string Number2)
{
int num1 =
Convert.ToInt32(Number1);
int num2 =
Convert.ToInt32(Number2);
return num1 + num2;
}
public int
SubRest(string Number1,
string Number2)
{
int num1 =
Convert.ToInt32(Number1);
int num2 =
Convert.ToInt32(Number2);
return num1 - num2;
}
public int
MulRest(string Number1,
string Number2)
{
int num1 =
Convert.ToInt32(Number1);
int num2 =
Convert.ToInt32(Number2);
return num1 * num2;
}
public int
DivRest(string Number1,
string Number2)
{
int num1 =
Convert.ToInt32(Number1);
int num2 =
Convert.ToInt32(Number2);
return num1 / num2;
}
}
}
Configuring Service
This section is very important. We need to configure the service for both
basicHttpBinding and webHttpBinding .
Very first we need to set the service beahavior as below ,
After setting the Service behavior , we need to set EndPoint behavior for REST
enabled EndPoint as below,
Next we need to create EndPoints , SOAP EndPoint with basicHttpBinding would get
created as below,
In above configuration ,
Name of the endpoint is SOAPEndPoint. You are free to give any name. Howevere at time of consuming the service this endpoint name is required.
This endpoint will be available at baseaddress/soap address.
Binding used in endpoint is basicHttpBinding
Contract is IService1. If you remember , we created this contract for the SOAP .
Now we need to create REST EndPoint as below,
In above configuration ,
Name of the endpoint is RESTEndPoint.
REST Service will be called at the URL baseaddress/rest/add/parameter1/parameter2
Binding used is webHttpBinding
Endpoint configuration is restbehavior .We set endpoint behavior with this name previously.
Putting all together service configuration will
look like as below,
<?xml
version="1.0"?>
<configuration>
<system.web>
<compilation
debug="true"
targetFramework="4.0"
/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior
name
="servicebehavior">
<serviceMetadata
httpGetEnabled="true"/>
<serviceDebug
includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior
name="restbehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service
name
="MultipleBindingWCF.Service1"
behaviorConfiguration
="servicebehavior"
>
<endpoint
name
="SOAPEndPoint"
contract
="MultipleBindingWCF.IService1"
binding
="basicHttpBinding"
address
="soap"
/>
<endpoint
name
="RESTEndPoint"
contract
="MultipleBindingWCF.IService2"
binding
="webHttpBinding"
address
="rest"
behaviorConfiguration
="restbehavior"/>
<endpoint
contract="IMetadataExchange"
binding="mexHttpBinding"
address="mex"
/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules
runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Now service is ready to be hosted. For purose of this post I am hosting it
cassini server.
Consuming Service
Service is enabled for both SOAP and REST version. So consumption of service
needs to be done accordingly.
Consumption of SOAP Service can be done in usual way in .Net client by adding
Service Reference and making a call to the service as below,
static
void CallingSOAPfunction()
{
Service1Client proxy =
new Service1Client("SOAPEndPoint");
var result = proxy.Add(7, 2);
Console.WriteLine(result);
}
If you notice, I am providing endpoint name to explicitly say which endpoint of
the service need to be called.
REST Service is working on JSON message format. For deserlization of the
message, I am using DataContractJsonSerializer. This class is in the namespace
System.Runtime.Serialization.Json.
static
void CallingRESTfunction()
{
WebClient RESTProxy =
new WebClient();
byte[] data=
RESTProxy.DownloadData(new
Uri("http://localhost:30576/Service1.svc/Rest/add/7/2"));
Stream stream =
new MemoryStream(data);
DataContractJsonSerializer obj =
new
DataContractJsonSerializer(typeof(string));
string result =
obj.ReadObject(stream).ToString();
Console.WriteLine(result);
}
In above code I am downloading data from REST Uri using WebClient and
deserlaizing that using DataContractJsonSerializer.
Now you know how to enable REST and SOAP on same WCF Service. I hope this post
is useful. Thanks for reading.