RESTful WCF Architecture – Hosting RESTful WCF Services in IIS

Inspired by the book RESTful .NET: Build and Consume RESTful Web Services with .NET 3.5.

Hosting in IIS [managed hosting] offers the following advantages:

  • Process setup and shutdown.
  • Process pooling and recycling.
  • Application restart [recycle] when configuration changed.
  • Enhanced security model.
  • Management tools.
  • Caching management.
  • Proven hosting platform written, debugged by A-team @MS.
  • Officially supported MS product/technology.

Hosting WCF in IIS – Quick & Dirty

Following are quick steps to expose WCF service via IIS and svc file using Visual Studio.

  • Create ASP.NET Empty Web Application. The application will provide a container for RESTful WCF services – files with svc extension. When IIS receives a request to resource with svc extension it routes to WCF handler. Look for *.svc extension as a path and its corresponding handler which is System.ServiceModel.Activation.HttpModule in IIS manager under Handler Mappings.
  • Add WCF Service. Visual Studio creates three files. For example, if you create RESTfulWCF service these files are created:
    • RESTfulWCF.svc – the file that glues the request routed by IIS and the service implementation. This is a simple text file that should look similar to this:

<%@ ServiceHost Language="C#"
Debug="true"
Service="RESTfulWCFHostedInIIS.RESTfulWCF"
CodeBehind="RESTfulWCF.svc.cs" %>

    • IRESTfulWCF. cs service’s interface with contract attributes decoration. It’s a common WCF practice to separate the interface and the implementation when building WCF services.
    • RESTfulWCF.svc.cs the code behind file that implements the service based on the IRESTfulWCF.cs.
  • Configure web.config.

Hosting WCF in IIS – Componentaized Approach

Another approach is to componentize the service into separate assembly. The main benefit of the approach is complete separationg or componentization of the service and how it’s exposed to the external world. Another huge benefit is this approach eliminates the need of messing with web.config.

Following are the steps needed to expose the WCF component that implements RESTful WCF service via svc file hosted in IIS:

Summary of steps:

  • Step 1 - Create class library project.
  • Step 2 - Implement RESTful resource.
  • Step 3 - Define RESTful WCF service interface.
  • Step 4 - Implement RESTful WCF service based on the interface.
  • Step 5 - Create empty web project.
  • Step 6 - Create new svc file.
  • Step 7 - Edit web.config file.
  • Step 8 - Test RESTful WCF service hosted in IIS.

Rest of the post is the detailed walkthrough of the above steps.

  • Step 1 - Create class library project. The purpose of the class library to hold the implementation of the RESTful WCF service. It will hold all related artifacts – entities, service interfaces, and the service implementation. Another approach would be separating all three into three different class libraries [assemblies]. This is even better approach for componentization and reuse which I have taken in my previous posts for solution architecture - Step 1: Structure Your Solution, Step 2: Design Your Entities & Business Components, Step 3: Design Your Cross Cutting Utilities, Step 4: Design Your Presentation Layer – Part I , Step 4: Design Your Presentation Layer – Part II. For now I’ll keep it simpler but still componentized into one single class library but still separated from how it’s exposed – in my case svc file hosted in IIS. Create ether Class Library or WCF Service Library which just adds required for WCF references saving few clicks and adding namespaces. Call it RESTfulWCFLibrary. Delete IService.cs and Service.cs created by default. Add reference to System.ServiceModel.Web.
  • Step 2 - Implement RESTful resource. Create new cs class and call it User. It will represent the entity, the resource being exposed and manipulated by the RESTful WCF service. Paste the following implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

 

namespace RESTfulWCFHostedInIIS
{
    //SINCE I USE DATA CONTRACT THE SERIALIZED XML WILL BE
    //BUILT BASED ON ELEMENTS vs. ATTRIBUTES
    [CollectionDataContract(Name="users",Namespace="")]
    public class Users: List<User>
    { }

    [DataContract(Name = "user", Namespace = "")]
    public class User
    {
        [DataMember(Name = "id", Order = 1)]
        public string UserId;
        [DataMember(Name = "firstname", Order = 2)]
   public string FirstName;
        [DataMember(Name = "lastname", Order = 3)]
        public string LastName;
        [DataMember(Name = "email", Order = 4)]
        public string Email;
    }
}

  • Step 3 - Define RESTful WCF service interface. It’s common practice to separate WCF decorated interface from it’s implementation. I follow the practice here. Create new cs interface file, call it IUserService, and paste the following interface definition:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;

 

namespace RESTfulWCFLibrary
{
    [ServiceContract]
    interface IUserService
    {
        [WebGet(UriTemplate = "/users",
   ResponseFormat = WebMessageFormat.Xml)]
        [OperationContract]
        Users GetAllUsers();

        [WebInvoke(UriTemplate = "/users",
                   Method = "POST",
                   RequestFormat = WebMessageFormat.Xml,
         ResponseFormat = WebMessageFormat.Xml)]
        [OperationContract]
        User AddNewUser(User u);

 

        [WebGet(UriTemplate = "/users/{user_id}",
                ResponseFormat = WebMessageFormat.Xml)]
        [OperationContract]
        User GetUser(string user_id);
    }
}

  • Step 4 - Implement RESTful WCF service based on the interface. Next step is adding actual implementation of the RESTful WCF service based on the interface I have just defined in previous step. Create new cs class file, name it UserService, and paste the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;

 

namespace RESTfulWCFLibrary
{
   public class UserService : IUserService
    {
        static Users _users = new Users();
        public Users GetAllUsers()
        {
            GenerateFakeUsers();
            return _users;
        }
        public User AddNewUser(User u)
        {
            u.UserId = Guid.NewGuid().ToString();
            _users.Add(u);
            return u;
        }
        public User GetUser(string user_id)
        {
            var u = FindUser(user_id);
            return u;
        }
        private User FindUser(string user_id)
        {
            return new User() { FirstName = "alik",
                                LastName = "levin",
                                Email = alikl@microsoft.com,
                                UserId = "1" };
        }
        private void GenerateFakeUsers()
        {
            _users.Add(new User() { FirstName = "alik",
   LastName = "levin",
   Email = alikl@microsoft.com,
                                    UserId = "1" });
            _users.Add(new User() { FirstName = "alik",
                                    LastName = "levin",
                                    Email = alikl@microsoft.com,
                                    UserId = "1" });
        }
    }
}

 

  • Step 5 - Create empty web project. Create ASP.NET empty web application project. Name it RESTfulWCFEndPointsHostedIIS. It will hold the svc files hosted in IIS. These files will serve as actual end points where incoming requested will be routed. Switch to RESTfulWCFLibrary project and configure to build its assmebly, RESTfulWCFLibrary.dll, into RESTfulWCFEndPointsHostedIIS bin folder. To do so, go to RESTfulWCFLibrary’s property page, click on Build tab, and provide this path in Output path: ..\RESTfulWCFEndPointsHostedIIS\bin\
  • Step 6 - Create new svc file. While in RESTfulWCFEndPointsHostedIIS create new WCF Service, name it RESTfulWCFUsersServiceEndPoint. Delete IRESTfulWCFUsersServiceEndPoint.cs and RESTfulWCFUsersServiceEndPoint.svc.cs files created by default. Open RESTfulWCFUsersServiceEndPoint.svc’s file markup by double clicking it and paste the following markup. Notice the Factory attribute.

<%@ ServiceHost Service="RESTfulWCFLibrary.UserService"
                Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>

  • Step 7 - Edit web.config file. No changes needed for the web.config which is fantastic – no massive mess in it, leave it as is. It’s due to the fact we added Factory attribute in the svc file which take care if it all. Once more – no web.config mess! Done.
  • Step 8 - Test RESTful WCF service hosted in IIS. Follow the procedures similar to those outlined in Walkthrough: Build, Host, and Test Simple RESTful WCF Service – Step 4, Step 5, Step 6 to test the implementation. To identify the URI, right click on RESTfulWCFUsersServiceEndPoint.svc and then choose “Wiew In Browser” option. Copy the URL from the browser’s Address bar and paste it to Request Builder in Fiddler adding proper URI, for example, this URL https://localhost:49852/RESTfulWCFUsersServiceEndPoint.svc/users should return all users.