August 2013

Volume 28 Number 8

.NET Web Services - Building Cross-Platform Web Services with ServiceStack

By Ngan Le

I like working with Windows Communication Foundation (WCF) because there’s excellent support for the framework in Visual Studio. I find it rather easy to build a WCF Web service from scratch and get it up and running in my development environment without installing additional tools and redistributables. I’ll discuss my experiences with cross-platform development here, so you might be interested in this article if the following statements apply:

  • You’re already familiar with WCF and C#.
  • You need to build a cross-platform Web service.

I think we can all agree that writing cross-platform apps is at the very least an inconvenience, but sometimes unavoidable. If you’re anything like me—Windows-bound and heavily invested in C#—putting together a cross-platform Web service might entail significant overhead. This includes reconfiguring your beloved Windows computing environment to accommodate a completely different set of development tools and possibly learning yet another programming language. In this article, I’ll show how you can leverage the WCF likeness of ServiceStack (an open source .NET and Mono REST Web services framework) to accomplish such a task without ever leaving Visual Studio or the Microsoft .NET Framework environment.

About Web Services

A typical Web service is laid out as depicted in Figure 1.

A Typical Web Service Layout
Figure 1 A Typical Web Service Layout

The service layer is where you define your Web service interface. This is the only layer with which the client needs to interact to consume your Web service.

The business layer is usually heavy with business logic, obviously. This is where the meat of your Web service implementation resides, keeping your service layer light and focusing on client/server contracts and communication.

The data layer is meant to encapsulate your data access and provide abstracted data models for manipulation at the business layer.

In this article, I’ll focus on the service layer.

Remote Procedure Calls versus Data Transfer Objects

Some Web services take the Remote Procedure Call (RPC) approach, where each request is designed to resemble a function call:

public interface IService {
  string DoSomething(int input);
}

The RPC approach tends to make the Web service more susceptible to breaking interface changes. For example, in the preceding code snippet, if a later version of the Web service requires two inputs from the client to execute the DoSomething method—or needs to return another field in addition to the string value—a breaking change to old clients is unavoidable. Of course, you can always create a parallel DoSomething_v2 method to take two input arguments, but over time that would clutter your Web service interface and risk confusing your consumers, both old and new.

Conventional wisdom favors defining Web service interfaces geared toward the Data Transfer Object (DTO) model. The following code shows how the Web method DoSomething can be transformed under the DTO model:

public class DoSomethingRequest {
  public int Input { get; set; }
}
public class DoSomethingResponse {
  public string Result { get; set; }
}
public interface IService {
  DoSomethingResponse DoSomething(DoSomethingRequest request);
}

Following this school of thought, each Web method takes a single request DTO and returns a single response DTO. The idea is that adding new fields to the request DTO and response DTO won’t break older clients.

It’s worth noting that both RPC-style and DTO-style Web service interfaces are supported by WCF, but ServiceStack only supports the DTO style. ServiceStack embraces the principle of the remote DTO style of Web service interfaces, for less chattiness and more chunkiness in the Web service interface design. This is key to understanding ServiceStack, because the framework is designed in a way that reinforces the principle.

What Is ServiceStack?

As mentioned, ServiceStack is an open source, cross-platform Mono Web service framework, and it’s gaining popularity. Web services built with ServiceStack can run in a Windows environment with .NET code or in a Linux environment with Mono support. The OSes supported by Mono include:

  • Linux
  • Mac OS X, iOS
  • Sun Solaris
  • BSD
  • Microsoft Windows
  • Nintendo Wii
  • Sony PlayStation 3

For more information about the platforms supported by Mono, see mono-project.com/Supported_Platforms.

If you like working with the .NET Framework and WCF and are in need of deploying your .NET Web services in an environment other than Windows, ServiceStack is an ideal option. Due to the similarity of ServiceStack and WCF, the transition from one to the other requires little adjustment in terms of development environment and tools. You get to continue writing C# code inside Visual Studio.

ServiceStack enforces remote Web service best-practice, convention-based DTO standards for its Web service interface, while WCF leaves it to you to freely define a Web service API as you see fit. ServiceStack also provides an out-of-the-box response status object that can be used to compose the response DTO, encouraging a more direct and simplistic error-handling scheme. Although this can easily be implemented with WCF, it’s not an obvious route. Recent versions of ServiceStack also provide an exception-based error-handling mechanism that’s similar to—although not as sophis­ticated as—WCF fault-based error handling via fault contracts.

The standards enforced by ServiceStack are easily implemented in WCF with a little extra typing. However, in addition to portability, ServiceStack is a viable option to build a RESTful Web service because it establishes conventions that simplify HTTP URI routing. At the same time, ServiceStack forces each Web service request to be implemented in a separate class, promoting a natural separation of concerns for a RESTful service model.

ServiceStack also offers other perks, such as out-of-the-box logging and basic data validation utility. You can read more about ServiceStack at servicestack.net.

This article assumes that you have some familiarity with WCF and the .NET Framework. To better demonstrate how WCF concepts can translate to ServiceStack concepts, I’ll first implement the service layer in WCF. Then I’ll show you how to transform the WCF Web service into a cross-platform Web service by porting it to an equivalent Web service using ServiceStack.

Building a Simple WCF Web Service

To demonstrate how ServiceStack can serve as a substitute for WCF in a multiplatform environment, I’ll start with a simple WCF Web service.

The Web service is a trivial restaurant ticketing system called TicketService that implements the following service contract:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue();
  [OperationContract]
  void QueueTicket(Ticket ticket);
  [OperationContract]
  Ticket PullTicket();
}

The TicketService allows its clients to queue a new ticket, pull a ticket off the queue and retrieve a complete inventory of all tickets currently in the queue.

The Web service consists of three Visual Studio projects, as shown in Figure 2(running my sample solution, which can be downloaded at msdn.com/magazine/msdnmag0813, requires Visual Studio 2012 with Web Developer Tools and the .NET Framework 4.5).

WCF Ticket Service Visual Studio Projects
Figure 2 WCF Ticket Service Visual Studio Projects

The three projects are briefly described as follows:

  • The TicketSystem.ServiceContract project is where the service interface is defined. 
  • The TicketSystem.TicketProcessor project contains the implementation details of the Web service business logic. This project contains no references to WCF.
  • The WcfServer project implements Ticket­System.ServiceContracts and hosts the Web service in IIS.

I also put together a WCF client to consume the TicketService. The WCF client is a console application that uses code generated from adding a WCF service reference to the TicketService to communicate with the Web service using SOAP over IIS. Here’s the client console implementation:

static void Main(string[] args) {
  Console.Title = "WCF Console Client";
  using (TicketServiceClient client = new TicketServiceClient()) {
    Ticket[] queuedTickets = client.GetAllTicketsInQueue();
    foreach (Ticket ticket in queuedTickets) {
      PrintTicket(ticket);
    }
  }
}

The client code implementation serves up the information shown in Figure 3.

The WCF Console Client
Figure 3 The WCF Console Client

Building an Equivalent ServiceStack Web Service

Prerequisite for Working with ServiceStackTo work with ServiceStack, first you must download the redistributables. The easiest way to do this is through the NuGet Visual Studio exten­sion that allows you to easily install and update third-party libraries and tools. You can download and install the NuGet client from nuget.codeplex.com. After NuGet is installed, you should see in Visual Studio the menu items shown in Figure 4.

The NuGet Package Manager Console in Visual Studio
Figure 4 The NuGet Package Manager Console in Visual Studio

Now I’ll do a step-by-step walk-through on how to create a ServiceStack Web service that’s the equivalent of the WCF Web service I built previously.

First, take the WCF Web service example as the starting point. Then remove the WcfClient and the WcfServer projects from the solution. These projects are specific to WCF, and they’ll be replaced with ServiceStack-compatible projects later.

In the Package Manager Console window, select the TicketSystem.ServiceContract project. At the command prompt, type “install-package ServiceStack,” as shown in Figure 5.

Installing ServiceStack Redistributables with NuGet Package Manager
Figure 5 Installing ServiceStack Redistributables with NuGet Package Manager

This step downloads the latest redistributables necessary to build a .NET Web service using ServiceStack. The redistributables are staged under a folder name “Packages” placed in your Visual Studio solution root folder. In addition, the DLL references are added to the TicketSystem.ServiceContract project. Along with that is a packages.config file created in your project root folder, providing you with version and runtime information for each ServiceStack DLL:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="ServiceStack" version="3.9.46" 
    targetFramework="net45" />
  <package id="ServiceStack.Common” version=“3.9.46”
    targetFramework="net45" />
  <package id="ServiceStack.OrmLite.SqlServer" version="3.9.45"
    targetFramework="net45" />
  <package id="ServiceStack.Redis" version="3.9.45"
    targetFramework="net45" />
  <package id="ServiceStack.Text" version="3.9.46"
    targetFramework="net45" />
</packages>

Next, convert the WCF data contracts defined in TicketSystem.ServiceContract project to something that ServiceStack can understand.

Convert WCF Data Contracts to ServiceStack Data Contracts WCF uses data contracts to establish the means of communication between the client and the server. ServiceStack does the same. WCF requires that appropriate attributes are put on any data object and data member you want to serialize and send over the wire; otherwise, WCF simply ignores them. This is where ServiceStack and WCF differ. ServiceStack will serialize all Plain Old CLR Objects (POCOs) referenced in the service contract and make them visible to the client side. Following are WCF and ServiceStack code representations of the same Ticket data contract reference in the TicketService interface.

Here’s the WCF <Ticket> data contract:

[DataContract]
public class Ticket {
  [DataMember]
  public int TicketId { get; set; }
  [DataMember]
  public int TableNumber { get; set; }
  [DataMember]
  public int ServerId { get; set; }
  [DataMember]
  public List<Order> Orders { get; set; }
  [DataMember]
  public DateTime Timestamp { get; set; }
}

Here’s the ServiceStack <Ticket> data contract:

public class Ticket {
  public int TicketId { get; set; }
  public int TableNumber { get; set; }
  public int ServerId { get; set; }
  public List<Order> Orders { get; set; }
  public DateTime Timestamp { get; set; }
}

The main difference between Service­Stack and WCF with regard to the service interface is that ServiceStack puts additional restrictions on the service interface. ServiceStack dictates that each unique request is identified by a unique request object, because there’s no concept of a Web service “operation” (that is, method name) in the world of ServiceStack. This means that you can’t reuse a request DTO across multiple service implementations with ServiceStack. All ServiceStack Web service operation contracts would equate to something similar to the following WCF service contracts:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue(GetAllTicketsInQueueRequest request);
  [OperationContract]
  void QueueTicket(QueueTicketRequest request);
  [OperationContract]
  Ticket PullTicket(PullTicketRequest request);
}

The preceding code is nothing more than the original RPC-style TicketService WCF service interface shown here, but transformed to embrace the DTO convention:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue();
  [OperationContract]
  void QueueTicket(Ticket ticket);
  [OperationContract]
  Ticket PullTicket();
}

Here’s the equivalent TicketService ServiceStack service interface:

public class GetAllTicketsInQueueRequest {}
public class QueueTicketRequest {
  public Ticket Ticket { get; set; }
}
public class PullTicketRequest {}
public interface ITicketService {
  List<Ticket> Any(GetAllTicketsInQueueRequest request);
  void Any(QueueTicketRequest request);
  Ticket Any(PullTicketRequest request);
}

ServiceStack supports different actions, such as Any, Get and Post. The choices you make here only impact HTTP requests. Specifying Any on a Web service request means the operation can be invoked by both an HTTP GET and an HTTP POST. This enforcement simplifies RESTful Web service implementation, which is beyond the scope of this article. To turn your ServiceStack Web service into a RESTful Web service, simply add URL [Route(…)]  attributes to your Web service request declarations.

Create an ASP.NET Hosted ServiceStack Web Service Now that you have the Web service interface defined for your ServiceStack Web service, it’s time to implement it and get it launched.

First, add an ASP.NET Empty Web Application. This is how I chose to host my ServiceStack Web service for convenience. It’s by no means the only method for hosting a Web service built on ServiceStack. You can also host such a service inside a Windows Service or in the form of a console application running under a Web server, or even independent of one.

I named this Visual Studio project ServiceStackServer. It’s the equivalent of the WcfServer project in the WCF service code sample.

Use the NuGet Package Manager Console to add ServiceStack references to ServiceStackServer as shown in Figure 6.

Add ServiceStack Library References to the ServiceStackServer Project
Figure 6 Add ServiceStack Library References to the ServiceStackServer Project

Now you have what you need to implement the ITicketService interface. The TicketService class must extend the ServiceStack.Service­Interface.Service class provided by the framework, like this:

public class TicketService : ServiceStack.ServiceInterface.Service,
  ITicketService {
  public List<Ticket> Any(GetAllTicketsInQueueRequest request) {
    // Implement ...
  }
  public void Any(QueueTicketRequest request) {
    // Implement ...
  }
  public Ticket Any(PullTicketRequest request) {
    // Implement ...
  }
}

Everything else is the same as the WCF implementation.

Next, add a Global Application Class named Global.asax to the ServiceStackServer project as shown in Figure 7. This is where you initialize your ASP.NET Web application.

Add Global.asax to ServiceStackServer
Figure 7 Add Global.asax to ServiceStackServer

You’re required to inherit from the ServiceStack.WebHost.End­points.AppHostBase class if you want to host your Web service inside an ASP.NET application. See Figure 8 for an example.

Figure 8 Hosting a ServiceStack Web Service Inside ASP.NET

public class Global : System.Web.HttpApplication {
  public class TicketServiceHost : 
    ServiceStack.WebHost.Endpoints.AppHostBase {
    // Register your Web service with ServiceStack.
    public TicketServiceHost()
      : base("Ticket Service", typeof(TicketService).Assembly) {}
    public override void Configure(Funq.Container container) {
      // Register any dependencies your services use here.
    }
  }
  protected void Application_Start(object sender, EventArgs e) {
    // Initialize your Web service on startup.
    new TicketServiceHost().Init();
  }
}

If running under IIS 7 and later, the configuration item exhibited in Figure 9 must be added to your Web.config file.

Figure 9 The Web.config File for IIS 7 and Later

<configuration>
  <system.web>...</system.web>
  <!--Required for IIS 7 (and above) -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <add path="*" name="ServiceStack.Factory"
        type="ServiceStack.WebHost.Endpoints.
          ServiceStackHttpHandlerFactory, ServiceStack"
        verb="*" preCondition="integratedMode"
          resourceType="Unspecified"
        allowPathInfo="true" />
    </handlers>
  </system.webServer>
</configuration>

When you launch your ServiceStack Web application, your service contracts are listed as operations metadata, as shown in Figure 10. Now your Web service is ready to accept client requests. In the next section, I’ll provide some consumer examples for the ServiceStack Web service.


Figure 10 TicketService Metadata

ServiceStack Built-in Clients

The ServiceStack development group is very outspoken against generated Web service client code, so the framework provides a set of built-in Web service clients listed under the Service­Stack.ServiceClient.Web namespace. All built-in clients implement ServiceStack.Service.IServiceClient. Those that support REST implement ServiceStack.Service.IRestClient.

Available clients include:

  • JsonServiceClient
  • JsvServiceClient
  • XmlServiceClient
  • MsgPackServiceClient
  • ProtoBufServiceClient
  • Soap11ServiceClient
  • Soap12ServiceClient

Each one supports a different serialization/deserialization format. Their usage is interchangeable because they implement a set of common interfaces.

To keep things simple, create a console application called ServiceStackClient to consume your ServiceStack Ticket­Service using the JsvServiceClient. If you want to try out a different client, just replace the following JsvServiceClient code with any of the available clients previously listed:

static void Main(string[] args) {
  Console.Title = "ServiceStack Console Client";
  using (var client = new JsvServiceClient("https://localhost:30542")) {
    List<Ticket> queuedTickets =
      client.Send<List<Ticket>>(new GetAllTicketsInQueueRequest());
    if (queuedTickets != null) {
      foreach (Ticket ticket in queuedTickets) {
        PrintTicket(ticket);
      }
    }
  }
}

The console application does the following:

  • Queries the TicketService for all tickets in the queue.
  • Prints out the resulting tickets it got back from the TicketService.

The console output is the exact same as that generated by the WCF client, shown in Figure 3.

More to Offer

This article only scratched the surface on what ServiceStack has to offer WCF users seeking cross-platform solutions. I haven’t even discussed ServiceStack’s support for streaming, async requests and message queues, for example.

As you can see, a few extra steps are required to build a ServiceStack Web service as opposed to a WCF Web service. However, I think the effort is rather negligible to transform the service layer of a Windows-bound WCF Web service into a multiplatform ServiceStack Web service. If I had gone a different route in search of platform independence—for example, using a Java Web service—the effort and the learning curve would’ve been much greater in comparison.

All things considered, if your Web service is destined to only run on a Windows OS, then WCF is arguably the better solution. There’s less overhead when building a WCF Web service from scratch in the Windows environment, and you don’t have yet another third-party redistributable to maintain and deploy to the target system.


Ngan Le is a senior software engineer working closely with WCF who recently started to explore ServiceStack as a cross-platform solution for Web services.

Thanks to the following technical expert for reviewing this article: Andrew Oakley (Microsoft)
Andrew Oakley is a Senior Program Manager on the patterns & practices team. Prior to becoming a Program Manager, Andrew spent two years as a Technical Evangelist for Visual Studio and the .NET platform. His current project focuses on data access guidance around building polyglot persistent systems using relational and NoSQL data stores.