Building WCF services capable of providing both Restful and SOAP services

There is a widespread adoption of  RESTful services recently. The  integration frameworks and the philosophy of ‘internet of things’ emphasise the need of quick integration of services in addition adhering of  the highest level of interoperability requirements.  In this article we’ll discuss about how to build web services which can be exposed  as SOAP based service as well RESTful service without having any additional plumbing as well as no duplicate code/implementation.

we will create a simple search service. The data contract is defined as below. The service – ISearchService  exposes a method  SearchByCriteria which takes Search criteria parameter.

Step 1 – Defining the service contract
   1:  namespace MySearchService.Contracts.ServiceContracts
   2:  {
   3:      [ServiceContract(Namespace = "")]
   4:      public interface ISearchService
   5:      {
   6:          [WebInvoke(Method = "POST", UriTemplate = "SearchByCriteria")]
   7:          [OperationContract(Name = "SearchByCriteria")]
   8:          [FaultContract(typeof (AuthorizationValidationException))]
   9:          [FaultContract(typeof (InvalidCriteriaException))]
  10:          SearchResults[] SearchByCriteria(SearchCriteria searchCrieria);  
  11:      } 
  12:  }   


The above is the interface specification of the service.  The line-6 & 7 annotate that this is exposed as RESTful service and SOAP services respectively. The RESTful annotation also define the URL template.

Step 2 – Implementation

The implementation really doesn’t matter

   1:  public  class SearchService:ISearchService
   2:  {
   3:          public SearchResults[] SearchByCriteria(SearchCriteria searchCrieria)
   4:          {
   5:                       //return the array of search result objects 
   6:          }
   7:  }

Step3 – Hosting the service

The idea of hosting a service is through a separate hosting project. This could be either a web project, console or windows service. The one thing we need to remember is that hosting application should be up and running and able to host the end points (also exports metadata of services)

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:    <system.serviceModel>
   3:      <services>
   4:     <service name="MySearchService.Business.Managers.SearchManager" behaviorConfiguration="SearchEngineTypeBehavior">       
   5:          <host>
   6:            <baseAddresses>
   7:              <add baseAddress="http://localhost:8080/" />
   8:            </baseAddresses>
   9:          </host>
  10:          <endpoint address="soap" binding="basicHttpBinding" contract="MySearchService.Contracts.ServiceContracts.ISearchService">
  11:            <identity>
  12:              <dns value="localhost" />
  13:            </identity>
  14:          </endpoint>
  15:          <endpoint name="rest" address="" binding="webHttpBinding" contract="MySearchService.Contracts.ServiceContracts.ISearchService" 
  16:          behaviorConfiguration="restEndpointBehavior">
  17:            <identity>
  18:              <dns value="localhost" />
  19:            </identity>
  20:          </endpoint>
  21:        </service>
  22:      </services> 
  23:      <behaviors>
  24:        <serviceBehaviors>
  25:          <behavior name="SearchEngineTypeBehavior">
  26:            <serviceMetadata httpGetEnabled="true" />
  27:            <serviceDebug includeExceptionDetailInFaults="true" />
  28:          </behavior>
  29:        </serviceBehaviors>
  30:        <endpointBehaviors>
  31:          <behavior name="restEndpointBehavior">
  32:            <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json" />
  33:          </behavior>
  34:        </endpointBehaviors>
  35:      </behaviors>
  36:    </system.serviceModel>


I have used a basic http binding for SOAP (just by looking at interoperability with other languages such as java, php) and webhttp binding for SOAP end points as shown in line 10 & 15. I have also defined an end point behaviour for RESTful service so that it emits the JSON as the default response . I have used a DI container (you may use MEF or Castle Windsor or any of your choice) to bind the implementation with interface. Now just build the service

You can now test the Restful endpoint  (e.g. )http://localhost:8080/SerarchEngine.svc/help as well as SOAP end point (http://localhost:8080/SerarchEngine.svc?wsdl)


One of the common validation of web service requests is inspection  the headers for security tokens. If we expose a service through multiple endpoints and protocols, then it become a bit more complex. In this scenario, it’s important to inspect both SOAP headers as well as http headers to validate the request. One of the methods of doing this to incorporate this validation in a base class of all our implementation of Service interfaces. I normally have common service base class(abstract)   for all service implementation in a project. This allow us to re-use such cross cutting concerns such as security logging etc.,

   1:   protected ServiceBase()
   2:          {
   3:          //Checking whether this is RESTful 
   4:              if (WebOperationContext.Current != null)
   5:              {
   6:                  GetHttpHeaders();
   7:                  // This can be obtained  
   8:                  //  WebHeaderCollection headersHttp = WebOperationContext.Current.IncomingRequest.Headers;
   9:                  // foreach (string key in headersHttp.Keys)
  10:                  //{
  11:                  ///.Validate HTTP headers
  12:                  //}
  14:              }
  15:              else
  16:              {
  17:                  GetSoapHeaders();
  18:                  //
  19:                  // OperationContext context = OperationContext.Current;
  20:                  //if (context != null)
  21:                  //{
  22:                  //validate SOAP header 
  23:                  //}
  24:              if (ObjectBase.Container != null)
  25:                  ObjectBase.Container.SatisfyImportsOnce(this);
  26:          }

The configurability of WCF (.NET 4.0 +) provide a wonderful way of exposing services across multiple endpoints and protocols. This increases the re-usability and interoperability of services.

Posted in Architecture, SOA