Wednesday, November 19, 2014

How to expose a WCF Service through many endpoints and multiple bindings

  
In this post we'll explore how to expose one single WCF Service through many  endpoints and multiple bindings. We'll have only one C# WCF code, and we'll make it implement several interfaces in order to expose several endpoints with many different bindings. Technically, we'll create several WCF services via creating several interfaces, but the C# class implementing them will be running the SAME CODE. We'll enable that unique C# class code to handle both Soap and HTTP requests, proceeding from backends calls, from jQuery Ajax calls, and from standard HTTP web calls. Some calls will be made programmatically in C# from some Application Back-End . Other, REST calls, will proceed from Ajax or from regular web calls. But ALL requests will be handled by the SAME C# service class.

How to expose a WCF Service through many endpoints and multiple bindings


Another interesting feature of this exercise will be, we are not creating a WCF Application, but adding a WCF Web Service to an existing MVC application.
The schema of our WCF app will be as follows : one unique C# Class, which implements two Interfaces as Services Contracts, finally exposed through three Endpoints:
How to expose a WCF Service through many endpoints and multiple bindings



One of the Endpoints will handle Soap calls, one HTTP web calls, and another one Ajax HTTP web calls. The first one will use an basicHttpBinding, and the former two, an webHttpBinding.

The WCF service we are building will handle HTTP requests based on the REST (REpresentational State Transfer) architecture, designed by Dr. Fielding at 2000. Our WCF sample will receive HTTP requests depending what it intends to do:

1) CREATE an item :     HTTP "POST" request
2) RETRIEVE  an item : HTTP "GET" request
3) RETRIEVE  ALL items : HTTP "GET" request

We'll want to create an WCF Web Service with CRUD functionality, which fetches and persists all data proceeding from a RESTful Web Service, based on a Model as follows:


Step 1 - Add a WCF Service to your application



Step 2 - Write the C# code for the WCF Service


[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class BlogService : IBlogService,IBlogService1
    {
        public string GetBlogs()
        {
            Models.BlogEntities ctx = new Models.BlogEntities();
            ctx.Configuration.ProxyCreationEnabled = false;
            List<Blog> data = ctx.Blogs.ToList();

            return new JavaScriptSerializer().Serialize(data);
        }

        public string GetBlog(string Id)
        {
            Models.BlogEntities ctx = new Models.BlogEntities();
            ctx.Configuration.ProxyCreationEnabled = false;
            int id = Convert.ToInt32(Id);
            Blog data = ctx.Blogs.Where(b => b.BlogID == id).FirstOrDefault();

            return new JavaScriptSerializer().Serialize(data);
        }

        public string CreatePost(Blog post)
        {
            Blog responsePost = post;
            return new JavaScriptSerializer().Serialize(responsePost);
        }
    }

Why do we create first the service implementation and after that the interfaces? Because we know exactly what our class is supposed to do, but only later we'll decide how many Service Contracts we'll need.

Step 3 - Create the C# interfaces as Service Contracts

In this example, we create two Service Contracts through two Interfaces: the first one look this way:



[ServiceContract]
    public interface IBlogService
    {
        [OperationContract]
        [WebGet]
        string GetBlogs();
        [OperationContract]
        [WebGet]
        string GetBlog(string Id);
        [WebInvoke(Method = "POST")]
        [OperationContract]
        string CreatePost(Blog post);
    }

The second one is similar but has the Operation Contracts names changed:


[ServiceContract]
    public interface IBlogService1
    {
        [OperationContract(Name = "GetBlogsSoapREST")]
        [WebGet]
        string GetBlogs();
        [OperationContract(Name = "GetBlogSoapREST")]
        [WebGet(UriTemplate="GetBlog1/{id}")]
        string GetBlog(string Id);
        [WebInvoke(Method = "POST")]
        [OperationContract(Name = "CreatePostSoapREST")]
        string CreatePost(Blog post);
    }

Then, we make our Service Class to implement the Interfaces:




Step 4 - Declare the WCF Service & its Endpoints

At the web.config, declare the service with its service behavior:



This service behavior states that the service metadata can be fetched , using the declaration:

<serviceBehaviors >
        <behavior  name="MultipleInterfacesAndEndpointsSvc" >
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>

Also we want that , at this development stage of our application, the errors could be view by us:
includeExceptionDetailInFaults="true"

Now we create three Endpoints:


 <service name="WCF_RESTful.BlogService" 
               behaviorConfiguration="MultipleInterfacesAndEndpointsSvc" >
       <endpoint 
         address="RESTfulAjax" 
         behaviorConfiguration="RESTfulAjaxBehavior"  
         binding="webHttpBinding" 
         contract="WCF_RESTful.IBlogService" />
        <endpoint 
          address="RESTfulNoAjax" 
          behaviorConfiguration="RESTfulNoAjaxBehavior"
          binding="webHttpBinding" 
          contract="WCF_RESTful.IBlogService1" />
        <endpoint 
          address="SoapEndpoint"  
          binding="basicHttpBinding" 
          contract="WCF_RESTful.IBlogService1" />
      </service>

The first two are for REST calls, that's why we use webHttpBinding. Each one exposes a different Service Contract (interface).
The last is for Soap calls, and therefore uses basicHttpBinding.
Now , to handle regular HTTP REST calls, we need to bind a "webHttp" behavior to the Endpoint:



 <behavior  name="RESTfulNoAjaxBehavior" >
          <webHttp />
        </behavior>

And to handle Ajax web calls, we declare another behavior using "enableWebScript", which also includes the "webHttp" directive:

Step 5 - Routing

Finally, reroute the path since we are inside an MVC application:

routes.IgnoreRoute("BlogService.svc/{*pathInfo}");


Build & run, and let's call our WCF from :
1) Soap request: we create a service reference in some MVC application, and discover our WCF with its methods:

The WSDL schema appears as this:



Now, just build the back end client Proxy and use the service.

2) Web HTTP REST request: XML response : 


And for getting just one record :



As you see, the response is given in XML format. Notice that we needed to call an "GetBlog1" method: that's because we defined an UriTemplate at the Operation Contract , and because of the format "GetBlog1/{id}" we don't need to specify the "GetBlog1?id=4" argument: 


3) Ajax REST HTTP request: Json response : 



Here, the response is Json. And to get only one record:




That's all!! 
In this tutorial we've learn How to expose a WCF Service through many endpoints and multiple bindings.  

Happy programming.....
      By Carmel Shvartzman
כתב: כרמל שוורצמן

No comments:

Post a Comment