How to enable REST and SOAP both on the same WCF Service

In this post I will show you, how to create a WCF Service with both flavor of SOAP and REST paradigm . For purpose of this post , I am going to create a Calculator Service with following characteristics

  • Serivice will have both SOAP and REST enabled
  • REST Service will have JOSN Message format

In later part of the post , I will show you the way to consume both types of Service in a managed (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 taken 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 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 above service explictly I am setting message format to JSON. So above service is 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

Service is implemented in 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 service for both basicHttpBinding and webHttpBinding .

Very first we need to set the service beahavior as below ,

clip_image002

After setting Service behavior , we need to set EndPoint behavior for REST enabled EndPoint as below,

clip_image003

Next we need to create EndPoints , SOAP EndPoint with basicHttpBinding would get created as below,

clip_image005

In above configuration ,

  1. 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.
  2. This endpoint will be available at baseaddress/soap address.
  3. Binding used in endpoint is basicHttpBinding
  4. Contract is IService1. If you remember , we created this contract for the SOAP .

Now we need to create REST EndPoint as below,

clip_image002[8]

In above configuration ,

  1. Name of the endpoint is RESTEndPoint.
  2. REST Service will be called at the URL baseaddress/rest/add/parameter1/parameter2
  3. Binding used is webHttpBinding
  4. 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 purpose 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

22 responses to “How to enable REST and SOAP both on the same WCF Service”

  1. While this is all well and good, this isn’t REST. This is RPC using XML or JSON as a message level. Note to your readers that if they want to build a real REST service, it is much more complicated than just adding an endpoint.

  2. […] How to enable REST and SOAP both on the same WCF Service […]

  3. Hi ,

    I would be very happy that if you share some article explaining REAL REST SERVICE… as of me this is WCF REST Service created using .Net Framework. Thanks

  4. Absolutely… There is a maturity model associated with endpoints that claim to be REST. You can find an explanation here: http://martinfowler.com/articles/richardsonMaturityModel.html.

    Effectively, what you are demonstrating above is at Level 0. There are no resources, there are no verbs, and there is no hypermedia. This is OK and it isn’t bad. I just don’t want readers to be under the impression that they have implemented REST.

  5. thanks I agree ..there is great scope to make complex REST with verbs and media.However purpose of this post was to display basic understanding of consumption in WP7. I may complex REST in further post.

    Thanks for your time and feedback 🙂

  6. […] How to enable REST and SOAP both on the same WCF Service […]

  7. Some of you out there tend to overstate things. The title of this article was “How to enable REST and SOAP both on the same WCF service”. It did not say “How to know everything there is to know about REST”! For what was intended by the article, I think the author did a great job and provided me with a succinct answer to a problem I have been working on most of the day; how do I add a second endpoint to an existing SOAPy WCF service in order to provide REST services to a jQuery/AJAX client. I understand that I have to worry about verbs and URI templates, and relative paths, etc., etc in order to provide a true REST service. But the author accomplished what the title of his article stated. He told me how to enable REST and SOAP both on the same WCF service (without killing mex by the way!).

  8. Dhananjay Kumar

    hey folks my purpose while writing this post was to focus on how to part ! I hope you find it useful

  9. Thanks for this post. It was really useful for me.

  10. Ramarao Pendela

    Is is possible to use bytearray datatype in rest wcf service?

  11. Dhananjay Kumar

    Glad to know that it was useful.

    Thanks
    /DJ

  12. Thanks for your post. It’s clearly and easy to understand.

  13. This is not working for me for some reason. I have configured everything as described, but when I attempt to call one of the methods that returns JSON, I get an AddressFilter mismatch at the EndpointDispatcher message. For instance, I’m trying to just pull up the url: http://myserver/myservice.svc/myRESTmethod. The SOAP version of the method works – but I’m consuming that through the code and not just accessing the method through the browser URL. Any help you can offer would be great! I have been working at this for a few days.

  14. Good attempt Dhananjay!

  15. I have done the task…both the services are running but when i’m calling methods from rest service giving an error as “The resource cannot be found”

  16. Thank you very much, exactly what I was looking for. I could test it within 10 minutes after reading this article. I just had to add 3 namespaces in the test project
    using System.Net;
    using System.IO;
    using System.Runtime.Serialization.Json;

  17. i am getting “You can change the name of one of the operations by changing the method name or using the Name property of OperationContractAttribute” error message.

  18. Very good post. A simple example that I could use to enable my webservice both for soap and rest. I learned a lot from the example. Thank you very much, Dhananjay!

  19. This was very helpful and helped solve a problem I was wrestling with. Thank you

  20. Excellent Example I Really Like It

  21. Great Thanks for making a complex task into simple one

Leave a comment

Create a website or blog at WordPress.com