RESTful Web Services with Windows Communication Foundation

In this post I am going to investigate how it is possible to create RESTful web services with Windows Communication Foundation. As well as discussing how the services are created I am also going to dig a bit deeper into some of the issues that can arise with this type of approach, especially the Same Origin Policy for browser based service execution, and how we can work around it.

What is REST?

I don’t really want to go too deep into REpresentational State Transfer, as there are lots of excellent resources already written that will do a far better job of explaining it, however a brief recap of the basics can’t hurt.

REST is an architectural pattern for accessing resources via HTTP. A resource can represent any type of item a client application may wish to access. A client can be a user or could be a machine calling a web service to get some data.

If you were creating a traditional RPC style service to return the details of a product you may well have created something that is called like this:

http://superproducts.com/products/getProduct?id=12345

In this example we have a verb (get) and a noun (Product). A RESTful version of this service would be something along the lines of:

http://superproducts.com/products/12345

In this example there is no explicit verb usage. Instead it is the HTTP verb GET that is used. In a RESTful web service it is the HTTP verbs (GET, POST, PUT, DELETE) that are used to interact with the resource.

GET – Used to return a resource in. It may be a simple product, as in the example above or it could be a collection of products.
POST – Used to create a new resource.
PUT – Used to update a resource. Sometimes PUT is also used to create a new resource is the resource is not present to update.
DELETE – Used to delete a resource.

The operations of a RESTful web service should be idempotent where appropriate to build resilience into the operations. It also makes sense that some verbs are not applicable to certain resources, depending on whether the resource is a collection of resources or a single resource (as we will see later).

REST is not a new idea – it was introduced by Roy Fielding in his 2000 doctoral dissataion, but has only recently been gaining serious traction against more widespread web service styles such as SOAP based XML. REST’s lightweight style and potential for smaller payloads have seen its popularity increase and major vendors have sought to add support for REST services into their products, including Microsoft.

A RESTful web service prescribes to the principles of REST, as well as specifying the MIME type of the data payload and the operations supported. REST does not specify the type of payload to be used and could really be any data format. In practice JSON has emerged as the defacto standard for RESTful services due to it’s lightweight nature.

Creating a WCF REST service

The WCF service will provide product information for some generic widgets.

The RESTful api for the service will support the following operations:

/Products

GET – Return a collection of products
POST – Add a new product to the product collection
PUT – Not supported, as we would want to edit the contents of the collection of products, not the collection itself.
DELETE – Not supported, as it would not really make sense to delete an entire collection of products

/Products/{productId} e.g. /products/12345

GET – Get the product represented by the product Id
POST – Not supported, as we cannot add anything at an individual product level
PUT – Update the product details.
DELETE – Delete the product

I am going to move failry quickly when it comes to creating the service. If you are not familiar with WCF (or need a refresher) I recommend that you have a look at the earlier series on creating WCF services.

I am going to make use of some of the new .Net 4.0 WCF features and not use a .svc file for the service. When creating RESTful services this has the advantage of making the URL look a little more ‘RESTful’, so instead of http://website/products.svc/1we can have http://website/products/1.

Lets create a new WCF application solution. I have thrown away the .svc file that the wizard has created for us. Rename the Interface to something sensible. I have called mine ProductService. Remember that this internal naming of the service contract and its operations in not exposed to the service once it is up and running. It makes sense to name the contract and operation in a sensible way for the project and them map it to a more REST friendly URL. We will see how to do this later in the post.

A RESTful service is in many respects similar to any other. It still follows the ABC of WCF. The service has an address at which the operations are invoked, it has a binding that specifies the way the service will communicate, and it also has a Contract that define the operations. The Contract for the ProductService looks like this:

[ServiceContract]
public interface IProductService
{
    [OperationContract]
    [WebInvoke(Method = "GET", UriTemplate = "", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    List<Product> GetProducts();

    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "", RequestFormat = WebMessageFormat.Json)]
    void CreateProduct(Product product);

    [OperationContract]
    [WebInvoke(Method = "GET", UriTemplate = "/{ProductId}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    Product GetProductById(string productId);

    [OperationContract]
    [WebInvoke(Method = "PUT", UriTemplate = "/{ProductId}", RequestFormat = WebMessageFormat.Json)]
    Product UpdateProductDetails(string productId);

    [OperationContract]
    [WebInvoke(Method = "DELETE", UriTemplate = "/{ProductId}", RequestFormat = WebMessageFormat.Json)]
    Product DeleteProduct(string productId);
}

It is the WebInvoke attribute that identifies that a service operation is a available via REST. The method property defines the HTTP verb that is to be used. The UriTemplate property allows a templated URL to be specified for the operation. Parameters for the URL are specified between {}. The RequestFormat and ResponseFormat attributes specify the datatype for the exchange. We are using JSON.

As we are not using .svc files we must supply some routing so WCF knows how to route the requests to the service. Open up the Global.asax (or create one if the project doesn’t already have one) and locate the Application_Start method and add in a new route.

protected void Application_Start(object sender, EventArgs e)
{
    RouteTable.Routes.Add(new ServiceRoute("Products"new WebServiceHostFactory(), typeof(ProductService))); 
}

This route tells WCF that when a request comes in for Products it is routed to the ProductService. As an aside if you were using custom service host factory, for example if you were using an IOC container to to inject dependencies, you could specify it here instead of the standard WebServiceHostFactory.

It is the URI template and the routing that allows us to provide the RESTful web service addresses. Although we have a service operation called GetProductById that takes a Product Id, the resource is accessed via a URL in the form of /Products/12345.

Now the implementation is out of the way we are ready to go. The actual implementation of the service operations is not very interesting as it has no bearing in the REST service, as it is just the same as any implementation of a WCF service contract interface.

“But wait” I hear you all shout, “you haven’t configured the service in the web.Config. You are correct. In this example I am going to use another feature of .Net 4.0 WCF: Default Configuration. This allows WCF to automatically create  default configuration for Bindings, including endpoint, behaviors and protocol mappings without the need to get your hands dirty in the Web.Config. Of course in a production environment it is likely that you would want more control over your configuration and this can be added to the config as required.

Lets try the service

In order to test the service we need to call the service. A simple test harness is required. I created a simple html page using  jQuery to call out to the service:

<!DOCTYPE html>
<html>
<head>
<title>WCF RESTful Web Service Example</title>
</head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
    <script type="text/javascript">

        var GetProductRequest = function () {
            $.ajax({
                type: "GET",
                url: "http://localhost:52845/products/",
                contentType: "application/json",
                dataType: "text",
                success: function (response) {
                    $("#getProductsResponse").text(response);
                    alert(response);
                },
                error: function (error) {
                    console.log("ERROR:", error);
                },
                complete: function () {
                }
            });
        };

        GetProductRequest();

    </script>

    <body>
        <h1>
        WCF RESTful Web Service Example
        </h1>
        <h2>
        GET Response
        </h2>
        <pre id="getProductsResponse"></pre>
    </body>
</html>

This simply uses jQuery’s ajax functionality to make a call to the service and output the response on the page. Lets run it. As another aside, if you are using ASP.NET Development Server when building and testing your services (and the chances are you probably are) then you will only be able to test GET and PUT methods, as others are not allowed and will return a 405 error. If you want to be able to test the PUT and DELETE methods I would recommend using IIS Express as your development web server.

I am using Chrome 21 and there appears to be a problem. If we look at the developer tools in Chrome (press F12) we can see that a request was made with the OPTIONS method, and it returned a status of 405 Method not allowed.  Also there is a message about the Origin nor being allowed by something called Access-Control-Allow-Origin. This is due to the Same origin policy.

The Same origin policy

The Same origin policy is a browser security concept that  prevent a client-side Web application running from one site (origin) from obtaining data retrieved from another site. This pertains mainly to cross site script requests. For them to be considered to be from the same origin they must have the same domain name, application layer protocol and port number.

Althouth the same origin policy is an important security concept with a lot of valid uses it does not help out legitimate situation. We need to be able to access the RESTful web service from a different origin.

Cross-origin resource sharing

Cross-origin resource sharing is a way of working with the restrictions that the same origin policy applies. In brief, the browser can use a Prefligh request (this is the OPTIONS method request we have already seen) to find out whether a resource is willing to accept a cross origin request from a given origin. The requests and responses are validated to stop man in the middle type attacks. If everything is okay the original request can be performed. Of course there is more to it than that, but that is all we need to know for now. More infomation is available in the
W3C spec for CORS.

As usual with browsers, CORS support is not universal, nor is it implemented in consistently across all browsers. In some browsers it is all but ignored (I am looking at you IE 8/9) We will need to ensure that the CORS support we add to the WCF service works in all situation. ‘When can I use Cross-Origin Resource Sharing‘  is a handy tool to see if your browser suppports CORS.

Dealing with an OPTION Preflight request in WCF

There are a couple of ways of dealing with CORS in WCF.

The first is some custom WCF Behaviours that can be applied to a service operation via an attribute. This approach has the advantage that it is possible to explicitly target which operations you want to be able to accept the cross domain requests, however it has quite an involved implementation.  A good overview can be found here.

I am going to focus on the second method, which is to intercept the incoming requests and check for the presence of the OPTIONS method and responding appropriately. I will show the code and them we can talk about how it works. Back to the Global.asax and the Application_BeginRequest method.

protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin""*");
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Cache-Control""no-cache");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods""GET, POST, PUT, DELETE");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers""Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age""1728000");
        HttpContext.Current.Response.End();
    }
}

As the method name suggests, this is called when a request is received. The first action is to add a Access-Control-Allow-Origin header to the response. This is used to specify URLs that can access the resource. If you are feeling generous and want any site (or origin) to access the resource you can use the * wildcard. The reason this header is outside of the check for the OPTIONS method is because sometimes CORS request do not send OPTIONS Prefligh requests for ‘simple’ requests (GET and POST). In this case they just send their origin and expect a response to be told if they can access the resource. This is dependent upon Browser CORS implementation. Remember when we first tried to call the service and we got an error saying that the Origin was not allowed by Access-control-Allow-Origin? That was because the response header did not contain this header with the correct entry.

The Cache-Control tell the requester not to cache the resource. The Access-Control-Allow-Methods specifies which http methods are allowed when accessing the resource. Access-Control-Allow-Headers specifies which headers can be used to make a request. Access-Control-Max-Age specifies how long the results of the Preflight response can be cached in the Preflight result cache.

There is a lot more information available about the CORS implementation. If you are looking for more information two of the best places are the W3C CORS Specification and the Mozilla Developer Network.

Lets give it another try.

Success. That’s all there is to it. Hopefully you will see that creating RESTful web services with WCF is easy. If you have any questions please feel free to leave a comment.

Windows Communication Foundation – Resolving MVC client WCF ChannelFactory dependencies with Unity

This series of posts will talk about Windows Communication Foundation, starting with an introduction into the technology and how to use it in you project, moving onto more advanced topics such as using an IOC container to satisfy dependencies in your services.
Posts in this series:

In the previous post we looked at how it was possible to use ChannelFactory to consume a WCF service from an MVC controller without using a proxy generated from the service WSDL.

The View action of the ProductController looked like this:

public ActionResult View(int productId)
{
    var factory = new ChannelFactory<IProductService>("WSHttpBinding_IProductService");
    var wcfClientChannel = factory.CreateChannel();
    var result = wcfClientChannel.GetProductById(productId);

    var model = new ViewProductModel 
        { 
            Id = result.Id, 
            Name = result.Name, 
            Description = result.Description 
        };

    return View(model);
}

This approach is less than ideal. The ChannelFactory creation is a little awkward and would be littered throughout the controller code creating duplication.

It would be better if we could just use Unity to inject a dependency to the WCF service in the Controller constructor like this;

private readonly IProductService productService;

public ProductController(IProductService productService)
{
    this.productService = productService;
}

public ActionResult View(int productId)
{
    var result = productService.GetProductById(productId);

    var model = new ViewProductModel 
        { 
            Id = result.Id, 
            Name = result.Name, 
            Description = result.Description 
        };

    return View(model);
}

If we tried to run this MVC would not be able to create the controller as there is no longer a parameterless constructor. Since version 3 MVC has introduced a mechanism for using IoC dependency resolution to resolve Controller dependencies through IDependencyResolver. Simply implement the interface and register using DependencyResolver.SetResolver.

If your needs are simple, then there are very simple implementations that will serve you well, however if you want to resolve dependencies that implement IDisposable then you need to be a bit more careful, as simple implementations often do not cater for IDisposable at all.

I am going to recommend a NuGet package to save us from implementing IDependencyResolver as I want to focus on how we can resolve WCF service dependencies. Unity.MVC3  is a nice little package that makes setting up Unity with MVC very easy. Although it was built for MVC3, version 4 uses the same mechanism and the package continues to function in the correct manner. You can read more about how the package functions here.

Install the package and open Bootstrapper.cs. Inside there is a BuildUnityContainer() section, this is where we need to register the dependencies with Unity. But when we ask for an IProductService what should we return? We need a new WCF channel for the IProductService based on the endpoint settings we defined in the web.config in the previous post. The code to do this is:

private static IUnityContainer BuildUnityContainer()
{
    var container = new UnityContainer();

    container.RegisterType<IProductService>(
        new ContainerControlledLifetimeManager(),
        new InjectionFactory(
            (c) => new ChannelFactory<IProductService>("WSHttpBinding_IProductService").CreateChannel()));          

    return container;
}

So what does this actually do? The first parameter is the type of lifetime manager we require. A Unity lifetime manager describes how dependencies are created and destroyed and the lifetime those dependencies have. In this case a ContainerControlledLifeTimeManager means that the same instance is returned for each call (also known as Singleton instance). This is desirable for creating WCF channels  as it is a comparatively expensive operation so we only want to create the channel once for the lifetime of the Unity container. There are several other Unity Lifetime Managers that are useful in different circumstances.

The next parameter introduces a factory function that tells Unity how to create the required concrete type. In our case we are going to create a new WCF Channel using ChannelFactory for the named client endpoint we set up in the web.config.

The only thing we need to do is to call Bootstrapper.Initialise() from Application_Start() in Global.asax and we are good to go. The controller is now completely decoupled from the WCF ChannelFactory, leaving a much cleaner implementation.

Posts in this series:

Windows Communication Foundation – Resolving WCF service dependencies with Unity

This series of posts will talk about Windows Communication Foundation, starting with an introduction into the technology and how to use it in you project, moving onto more advanced topics such as using an IOC container to satisfy dependencies in your services.
Posts in this series:

In this post I am going to use Microsoft Unity Inversion of Control container to resolve the dependencies for the ProductService implementation.

Most developers will already be familiar with the concept of Dependency Injection and will probably have used an IOC container such as Unity or Castle.Windsor at some point. In order to use Unity to resolve the dependencies in a service implementation a few steps must be taken to wire up Unity with WCF. This post will walk throught the steps to do this.

Adding Unity and creating the DI Wrapper

I have created a new project to hold all the DI related stuff. You may wish to put it somewhere else, which is fine. Into that project I have a added Unity via NuGet. The fisrt thing to do is to create a static wrapper for the Unity Container so we can be sure we are getting the same Unity container whenever we need to use it.

using Microsoft.Practices.Unity;

namespace WcfServiceApplication.DependencyInjection
{
    public static class DIWrapper
    {
        private static readonly IUnityContainer _container;

        static DIWrapper()
        {
           _container = new UnityContainer();   
        }

        public static IUnityContainer Container
        {
            get { return _container; }
        }
    }
}

The DIWrapper provided a static getter returning the UnityContainer. As it is a static class the constructor is guaranteed to run only once and ensures that a new UnityContainer is created. This same container will be returned whenever a call to DIWrapper.Container is made.

UnityServiceHostFactory

A service host does exactly as the name would suggest. A service such as the currect Prodcut Service can be hosted on the standard service host without any issues. Once we want to use Unity (or any other IOC container) we need to extend the ServiceHost functionality in order to resolve the dependencies in the service implementation. WCF uses a factory pattern to provide a layer of indirection between the hosting environment and the concrete type of the service required. If you don’t specify which ServiceHostFactory to use, you will get the default factory that returns an instance of the default ServiceHost.

To specify a ServiceHostFactory for a service it needs to be specified in the service .svc file like so:

<%@ ServiceHost 
    Language="C#" Debug="true" 
    Service="WcfServiceApplication.Implementation.ProductService" 
    Factory="WcfServiceApplication.DependencyInjection.WCF.UnityServiceHostFactory"
%>

If you do not specify a factory in the .svc file you will encounter the following error when trying to use the service.

“InvalidOperationException: The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.”

This is because the default behavior for WCF is to call the parameteless constructor, but if you are using constructor injection for the dependency the service implementation will not have one, so WCF does not know how to instantiate the service.

Obviously this factory does not exist so we had better create it. To do so we extend System.ServiceModel.Activation.ServiceHostFactory.

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace WcfServiceApplication.DependencyInjection.WCF
{
    public class UnityServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            return new UnityServiceHost(serviceType, baseAddresses);
        }
    }
}

All the factory needs to do is return a new instance of ServiceHost, so we just override CreateServiceHost to return our yet to be created new ServiceHost

UnityServiceHost

The new ServiceHost functionality is again very straight forward. System.ServiceModel is extended and a single method is overridden.

using System;
using System.ServiceModel;
using Microsoft.Practices.Unity;

namespace WcfServiceApplication.DependencyInjection.WCF
{
    public class UnityServiceHost : ServiceHost
    {
        public UnityServiceHost(Type serviceType, Uri[] baseAddresses)
            : base(serviceType, baseAddresses) { }

        public IUnityContainer Container
        {
            get { return DIWrapper.Container; }
        }

        protected override void OnOpening()
        {
            new UnityServiceBehavior(Container).AddToHost(this);
            base.OnOpening();
        }
    }
}

Inside the overridden OnOpening method a new UnityServiceBehavior is created (which we will create next) and added to the UnityServiceHost before the OnOpening method on the base ServiceHost is called.

UnityServiceBehavior

The System.ServiceModel.Description.IServiceBehavior interface provides a mechanism to extend or modify some aspect of an entire service. To use Unity with WCF we need to add some custom endpoint behaviour.

using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using Microsoft.Practices.Unity;

namespace WcfServiceApplication.DependencyInjection.WCF
{
    public class UnityServiceBehavior : IServiceBehavior
    {
        private ServiceHost serviceHost;

        public UnityServiceBehavior()
        {
            InstanceProvider = new UnityInstanceProvider();
        }

        public UnityServiceBehavior(IUnityContainer unity)
        {
            InstanceProvider = new UnityInstanceProvider();
            InstanceProvider.Container = unity;
        }

        public UnityInstanceProvider InstanceProvider { getset; }

        public void AddBindingParameters(
                ServiceDescription serviceDescription,
                ServiceHostBase serviceHostBase,
                Collection<ServiceEndpoint> endpoints,
                BindingParameterCollection bindingParameters) { }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (var cdb in serviceHostBase.ChannelDispatchers)
            {
                var cd = cdb as ChannelDispatcher;
                if (cd != null)
                {
                    foreach (var ed in cd.Endpoints)
                    {
                        InstanceProvider.ServiceType = serviceDescription.ServiceType;
                        ed.DispatchRuntime.InstanceProvider = InstanceProvider;
                    }
                }
            }
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }

        public void AddToHost(ServiceHost host)
        {
            if (serviceHost != null)
            {
                return;
            }

            host.Description.Behaviors.Add(this);
            serviceHost = host;
        }
    }
}

ApplyDispatchBehavior can be used to change run-time property values or insert custom extension objects such as error handlers, message or parameter interceptors, security extensions, and other custom extension objects. In the UnityServiceBehavior class ApplyDispatchBehavior is used to assign a custom InstanceProvider to the service endpoints.The InstanceProvider in this case is our own UnityInstanceProvider (the implementation of which is shown below).It is the InstanceProvider that will actually use Unity’s funcitonality to resolve the dependencies in the service impementation.

The behaviour of the Validate and AddBindingParameters methods does not need to change and so have empty implementations.

UnityInstanceProvider

This implementation of IInstanceProvider allow control over the instantiation of the service class. Our aim is for Unity to resolve the service type (ProductService in this example) and its dependencies.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using Microsoft.Practices.Unity;

namespace WcfServiceApplication.DependencyInjection.WCF
{
    public class UnityInstanceProvider : IInstanceProvider
    {
        public UnityInstanceProvider()
            : this(null) { }

        public UnityInstanceProvider(Type type)
        {
            ServiceType = type;
            Container = new UnityContainer();
        }

        public IUnityContainer Container { getset; }

        public Type ServiceType { getset; }

        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            return Container.Resolve(ServiceType);
        }

        public object GetInstance(InstanceContext instanceContext)
        {
            return GetInstance(instanceContext, null);
        }

        public void ReleaseInstance(InstanceContext instanceContext, object instance) { }
    }
}

In the UnityServiceBehavior constructor a new UnityInstanceProvider is created and the Unity Container from DIWrapper.Container is assigned as the Container. The GetInstance method then calles Container.Resolve(ServiceType) to resolve an instance of the required type. This is where Unity resolves the dependencies and returns an instance of the Service type with the dependencies satisfied. WCF can now happily use this instance for the service.

Add the dependency to the service

At present the ProductService does not have any dependencies so I will add one to a product repository from where we will return some data. The Prodcut service not looks like this:

using System.ServiceModel.Activation;
using WcfServiceApplication.Contract;
using WcfServiceApplication.Domain;
using WcfServiceApplication.Repository.Interface;

namespace WcfServiceApplication.Implementation
{
    public class ProductService : IProductService
    {
        private readonly IProductRepository productRepository;

        public ProductService(IProductRepository productRepository)
        {
            this.productRepository = productRepository;
        }

        public Product GetProductById(int productId)
        {
            return productRepository.GetProductById(productId);
        }
    }
}

Note that there is no paramaterless constructor, so this service can no longer be resolved via the standard WCF ServiceHost. I have kept the service implementation simple and just moved the logic that was there to the new repository.

using WcfServiceApplication.Domain;
using WcfServiceApplication.Repository.Interface;

namespace WcfServiceApplication.Repository
{
    public class ProductRepository : IProductRepository
    {
        public Product GetProductById(int productId)
        {
            return new Product
            {
                Id = productId,
                Name = "Product " + productId,
                Description = "A nice product"
            };
        }
    }
}

Configure Unity in Global.asax

Finally we need to configure Unity in the Global.asax of the ServiceHost. We are going to tell Unity to give us back a ProductRepository instance whenever a constructor is expecting an IProductRepository.

using System;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using WcfServiceApplication.DependencyInjection;
using WcfServiceApplication.Repository;
using WcfServiceApplication.Repository.Interface;

namespace WcfServiceApplication
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            ConfigureUnity();
        }

        protected void Session_Start(object sender, EventArgs e){}

        protected void Application_BeginRequest(object sender, EventArgs e){}     

        protected void Application_AuthenticateRequest(object sender, EventArgs e){}

        protected void Application_Error(object sender, EventArgs e){}

        protected void Session_End(object sender, EventArgs e){}

        protected void Application_End(object sender, EventArgs e){}

        private void ConfigureUnity()
        {
            // Configure common service locator to use Unity
            ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(DIWrapper.Container));

            // Register the repository
            DIWrapper.Container.RegisterType<IProductRepositoryProductRepository>();           
        }
    }
}

Now we are all ready to run the service. In the next post I will look at using Unity to resolve Channels for the MVC client so we can just inject the service interfaces into the MVC controller, removing the need to call the Channel factory code from the previous post each time we want a new Channel to consume a service.

Posts in this series:

Windows Communication Foundation – Consuming a WCF service with ChannelFactory

This series of posts will talk about Windows Communication Foundation, starting with an introduction into the technology and how to use it in you project, moving onto more advanced topics such as using an IOC container to satisfy dependencies in your services.
Posts in this series:

In An Introduction to WCF I talked a little about what WCF is and how it can be used, as well as creating a simple WCF service. In this post I want talk about how to consume WCF services in the most common situations.

There are two common scenarios when consuming WCF services; consuming a WCF service from a non WCF client via a proxy, and consuming a WCF service from a WCF client via a shared contract with ChannelFactory.

Consuming a WCF service from a non WCF client via a service proxy

A service proxy acts as an interface between the client and the service. It means that the client does not need to know anything about the implementation of the service other than the operations that are exposed. A downside to using a proxy is that if the interface of the service changes then the proxy will need to be regenerated. Using a service proxy will be necessary if you do not control the service you wish to consume.

To add a service proxy you can either use svcutil.exe or let Visual Studio generate the proxies for you (which uses svcutil.exe underneath) by right clicking on a project and selecting Add Service Reference.

I don’t really want to dwell on service proxies too much, as there is lots of information available already and it is not really very interesting. There is another way to consume a WCF service if you have more control over the service and are using WCF services to provide some separation of concerns in your application.

Consuming a WCF service from a WCF client using ChannelFactory

A real world example is probably the easiest way to describe the type of situation in which this approach is useful. Lets say I am creating an ASP.Net MVC application and I want to have some separation in the layers. Along side the MVC client I want to have a repository to take care of the persistence side of things and a service layer to take care of the business logic so that I can call a service method in the Controller of the client that will perform some operation and maybe talk to the repositories.

It is of course possible to have the services in-process, and for a small application it may be a sensible solution. When moving to a larger application it may be prudent make the service layer true services that can be deployed on a separate server (or server farm) to aid scalability and security. WCF is a ideal technology for these services. In this instance the WCF services are only to be used by this particular application and so we can use some more WCF functionality to remove the need to keep generating service proxies. You will definitely appreciate this as you develop your application. Regenerating proxies gets a little tiresome after the hundredth time.

To use ChannelFactory it is necessary that both client and service host share the same operation and data contracts. Usually this means that the service interfaces (operation contracts) and data contracts are separated into separate assemblies so they can be shared between projects.

What is ChannelFactory anyway?

According to MSDN it is “A factory that creates channels of different types that are used by clients to send messages to variously configured service endpoints”. WCF uses a Channel Model layered communication stack to communicate between endpoints. As with other stacks such as TCP/IP the Channel stack provides an abstraction of the communication between the corresponding layer for the sending and receiving stack.

The stack provides an abstraction for how the message is delivered, the protocol to be used and other features such as reliability and security. Messages flow through the Channel stack and are transformed by a particular Channel, for example the transport channel transforms the message into the required communication format. Above that the protocol channels might encrypt the message or add headers. It is the ChannelFactory that is used to create the channel stack for a particular binding. For more information on the Channel Model see this MSDN article.

Using ChannelFactory to call a service

In the previous post I created a simple Product service with a single operation. I am going to extend that example to add an MVC client that uses ChannelFactory to consume the service. I will break the process into a number of steps to make it easy to follow.

1) Reorganise the solution to separate the interface and data contracts

I have moved the service interface and the data contracts into separate assemblies so they can be shared with the client. As mentioned briefly in the previous post, the data contracts would usually be Data Transfer Objects and not domain entities. For this example I have used domain entities an data contracts for ease. I have also added an Asp.Net MVC 4 project that will act as the client and consume the WCF service.

2) Add the WCF service model configuration to the client Web.config

Just as we added some configuration to the Web.config of the service project to let WCF know how we want the service to work, we also need to add some similar configuration to the client Web.config.

<system.serviceModel>
    <client>
        <endpoint 
            address="http://localhost:53313/ProductService.svc" 
            binding="wsHttpBinding" 
            contract="WcfServiceApplication.Contract.IProductService" 
            name="WSHttpBinding_IProductService"/>          
    </client>
</system.serviceModel>

We can once again see the ABC of WCF. The address is the URL of the service which I have set this to the URL of the Service when it is running0 from Visual Studio. When the client is deployed the address needs to be changed accordingly. The binding needs to be the same as the binding of the service you want to consume. The contract is the service contract from the shared assembly. Finally a name is used so ChannelFactory can get the configuration details by name.

3) Use ChannelFactory to call the service

As this is an MVC application, a service would generally be called from a controller. I have created a ProductController and a couple of views. The simple application works like this: a user enters a Product Id and selects to search. The product details are then displayed. The controller action that call the service looks like this:

public ActionResult View(int productId)
{
    var factory = new ChannelFactory<IProductService>("WSHttpBinding_IProductService");
    var wcfClientChannel = factory.CreateChannel();
    var result = wcfClientChannel.GetProductById(productId);

    var model = new ViewProductModel 
        { 
            Id = result.Id, 
            Name = result.Name, 
            Description = result.Description 
        };

    return View(model);
}

Firstly, create a new factory for the service contract required. The constructor takes the name of an endpoint from the configuration. A channel is then created based on the service contract and the named endpoint configuration. It is then possible to call an operation on the channel and return some results. I have then used the results in the model for the view.

Lets have a look at the MVC client application in action. I am not going to win any awards for design…

Lets search for a product:

And view the results:

Conclusion and next steps

As you can see from the above example, using ChannelFactory is a very easy way of calling a service when you have access to the service and data contracts. However if you were calling multiple services from a controller it would be better to get some reuse and not have to keep creating the factory and channel over and over again. It is possible to create a helper method to control the creation and use of factories but there is a better way.

You are probably already using Dependency Injection in your application via an Inversion of Control container such as Castle Windsor or Unity. It turns out that is it very easy to inject dependencies into service and also to inject a channel directly to where it is needed in your application. In the next post I will look at injecting dependencies into the service implementation.

Posts in this series:

An Introduction to Windows Communication Foundation – Creating a basic service

This series of posts will talk about Windows Communication Foundation, starting with an introduction into the technology and how to use it in you project, moving onto more advanced topics such as using an IOC container to satisfy dependencies in your services.
Posts in this series:

Before the introduction of Windows Communication Foundation (WCF) in 2006 there were lots of different Microsoft technologies for building distributed systems. ASP.NET Web Services (ASMX), Web Service Enhancements (WSE) extensions, Microsoft Message Queue (MSMQ), the Enterprise Services/COM+ runtime environment and .NET Remoting to name the key ones. Microsoft were keen to point out that there was nothing wrong with these technologies, simply that there are too many of them. Building a distributed system required you to pick one of them as a fundemental technology which would send you down a specific technology strategy.

WCF is a single programming model that unifies all of the above approaches and more, and allows for a single technology choice to be used to support many different distributed systems scenarios.

Microsoft  describes WCF as

“a framework for building service-oriented applications. Using WCF, you can send data as asynchronous messages from one service endpoint to another. A service endpoint can be part of a continuously available service hosted by IIS, or it can be a service hosted in an application. An endpoint can be a client of a service that requests data from a service endpoint. The messages can be as simple as a single character or word sent as XML, or as complex as a stream of binary data.”

Don’t be put off by the reference to the often over hyped service orientation. WCF services can be used in many situations. It is often thought of as being too”enterprisy” for small applications. This is not the case at all. Services can be hosted in applications (Console, Winforms, WPF) as well as IIS and even a Windows Service. This opens up lots of possibilities for developing distributed applications. Many message formats are supported, including SOAP, plain XML and JSON. New formats are added as they gain traction within the industry.

If you have been reading about WCF you may have seen the ABC mnemonic when talking about endpoints;

  • A – Address: Where is the service?
  • B – Binding: How do I talk to the service?
  • C – Contract: What can the service do for me?
In WCF all communication occurs through an Endpoint. The ABC of WCF translates to some concrete steps that are followed when creating a WCF service:
  • You define a contract and implement it on a service – The language may be new but the concepts will be familiar. A WCF contract is an interface that defines service operations. The service implementation is simply an implementation of that interface.
  • You define a service binding that selects a transport along with quality of service, security and other options – This is usually done in configuration, but can be done in code if required.
  • You deploy an endpoint for the contract by binding it to a network address.  Configuration again. Tell WCF which contract interface should be associated with a particular endpoint.

Don’t worry if some of the terminology or concepts are new to you, we will cover these in more detail in the next section.

Creating you first WCF Service

Lets go ahead and create a new WCF Service Application project in Visual Studio, either in a new solution or an existing one, it doesn’t really matter for the purposes of this example. Be sure to target .Net3.5. There is a reason for this as .Net4.0 has lots of features to simplify configuration, but it is not that helpful to have lots of things defaulted behind the scenes when we are trying to understand how things work.

Visual Studio helpfully(?!) creates a service for us named Service1. A quick rename and we are done, right? Not quite. Although this service would work correctly, the way it has been created would not really be of any practical use in any but for the smallest of applications. The service implementation is in a code-behind on the .svc file and the interface is in the same file as the data contracts (the service model).

Lets just delete the files we don’t want and start again. Start with the code-behind file Service1.svs.cs and IService1.cs. Lets leave the Web.config for now as we can reuse the configuration already in there. If you were writing a full size application you may well want to structure your solution into several different projects for the different parts of the application. For this introduction I am going to use folders.

The first thing I am going to do is create a service contract. Remember that a service contract is just an Interface. Create a folder called Contract and an Interface within it, IProductService seems like a sensible name. Add a ServiceContract attribute to the interface. You will need a using statement for System.ServiceModel. Now we can add a service operation; called GetProductById(int productId). Each operation needs to have an OperationContract attribute. If this attribute is missing the operation will not be visible to WCF. The IProductService interface looks like this:

using System.ServiceModel;
using WcfServiceApplication.Domain;

namespace WcfServiceApplication.Contract
{
    [ServiceContract]
    public interface IProductService {

        [OperationContract]
        Product GetProductById(int productId);
    }
}

You will notice that the service operation returns a Product. I have defined this in the Domain folder. If an object is to be sent over the wire by WCF it needs to be attributed at the class level with DataContract and at the method level with DataMember (you will need to add a using statement for System.Runtime.Serialization) to indicate that the object can be serialised. I do not really want to get into the debate about returning Domain objects versus returning Data Transfer Objects from services at this stage as it doesn’t add much to the topic at hand. I will just say that for the purposes of this walk through I will use Domain objects, but for a non trivial application I would use DTO’s. The Product class looks like this:

using System.Runtime.Serialization;

namespace WcfServiceApplication.Domain
{
    [DataContract]
    public class Product
    {
        [DataMember]
        public int Id { getset; }

        [DataMember]
        public string Name { getset; }

        [DataMember]
        public string Description { getset; }
    }
}

Now we can implement the interface so the service can do something. I have given it a trivial implementation. In a real application the service would be responsible for doing something interesting such as performing some calculations or getting some data from somewhere.

using WcfServiceApplication.Contract;
using WcfServiceApplication.Domain;

namespace WcfServiceApplication.Implementation
{
    public class ProductService : IProductService
    {
        public Product GetProductById(int productId) {
            return new Product {
                                       Id = productId, 
                                       Name = "Product" + productId, 
                                       Description = "A nice product"
                               };
        }
    }
}

The next step is to tell the .svc file to use the new implementation we have created. Rename the file to productService.svc and edit the contents to point to the implementation.

<%@ ServiceHost Language="C#" Debug="true" 
    Service="WcfServiceApplication.Implementation.ProductService" %>

We only have the Web.config to go before we have a working service. Open Web.config and find the system.serviceModel section which contains the configuration for the WCF services.

In the system.serviceModel there are two further sections: services and behaviors.

Services – All services have their own section under services. There is just one right now which is incorrectly configured and we will fix things up as we go. The service has two attributes and one or more endoint elements:

  • name attribute – this should match the service attribute from the ProductService.svc, which is WcfServiceApplication.Implementation.ProductService.
  •  behaviorConfiguration attribute – this should match a service behaviour. We havent encountered one yet (its coming up in the behaviors section) so lets just change the value to WcfServiceApplication.ProductServiceBehavior in anticipation.
  • endpoints – As mentioned earlier, an endpoint is how a WCF service communicates with the outside world. A service can have one or more endpoints. Our example has two. Lets have a closer look at the first one.
    • address = “” – this is a relative address, which means that the address of this service will be relative to the base address. This is the most common address but can be different. It is also possible to add a base address if you want things to work differently. A good introduction can be found here.
    • binding=”wsHttpBinding” – a binding is used to define how to communicate with an endpoint. It has a protocol stack that determines things like security and reliability from messages sent to the endpoint. It describles the transport protocol to use when sending to the endpoint (HTTP, TCP etc). It also describes the encoding of the messages that are sent to the endpoint (text/xml etc). WCF has some binding to choose from that cover a variety of scenarios. We are using wsHttpBinding which offers good support for interoperation with other services that support the WS-* standards. Other bindings can be used depending on whether you need backwards compatibility with old asmx style services, or whether you want high performance when building WCF services that are also to be consumed by a WCF client for example. More information about bindings can be found here.
    • Contract – this should be changed to the location of the contract we created early, which is WcfServiceApplication.Contract.IProductService.

You may have noticed that this is the ABC of WCF I mentioned earlier. There is another endpoint with address=”mex”. This is to allow clients to be able to get the metadata for the service via SOAP calls. We can leave it in as we plan on using the metadata at a later stage. The services section now looks like this:

<services>
    <service name="WcfServiceApplication.Implementation.ProductService" behaviorConfiguration="WcfServiceApplication.ProductServiceBehavior">
      <endpoint address="" binding="wsHttpBinding" contract="WcfServiceApplication.Contract.IProductService">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
  </services>

Behaviors – This section can have a number of behaviours which can be applied to a service. Remember that we changed the behaviorConfiguration value and we need to change the name of the behavior to be the same to enable our service to find it. The behavior has two elements:

  • serviceMetadata httpGetEnabled=”true” – this enables metadata exchange and also allows the WSDL to be access by a special URL (which is the service url with ?wsdl at the end). You don’t always need metadata exchange, but we will be using it later.
  • serviceDebug includeExceptionDetailInFaults=”false” – do we want to show useful debugging info? The default is false and will keep it that way. This may be useful if you are debugging a service but should not be used in a production environement.

The behavior section now looks like this:

 <behaviors>
      <serviceBehaviors>
        <behavior name="WcfServiceApplication.ProductServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

Thats it. We are ready to run the service for the first time. The easiest way is using the WCF Test Client. highlight ProductService.svc in SolutionExplorer and hit F5. All being well WCF Test Client should load with the service visble. If you get any errors when you load the service it is very likely that there is a typo somewhere in either the files or the web.config.

Under the service you should be able to see the service along with the single service operation GetProductById(). Select the method to bring up the request and response panels for the method. You should be able to add a product Id (any number will do) and hit invoke to see the outcome.

That’s all there is to it. Of course there are a lot more configuration possibilities for more advanced scenarios, and we will cover some in future posts. In the next post I will cover how to create a client application to consume the WCF service we just created.

Posts in this series: