CHAPTER 2
In this chapter, we will go through various concepts and background information about ServiceStack including routing, dependency injection, content negotiation, and validation and error handling.
The base entry point for ServiceStack is the AppHost (application host). The concept of the application host is to define a central point for configuring and wiring the request to the service. There can be only one application host per application.
In general, a ServiceStack service can be hosted on Internet Information Services (IIS) as a console application, Windows Service, or mixed with an ASP.NET or ASP.NET MVC application.
Web applications will implement the AppHostBase class while the console and Windows Service applications will implement AppHostHttpListenerBase.
In a web application, the application host has to be started only once when the application starts. This can be done in the Global.asax.cs file by calling the Init method in the Application_Start method. The following code shows the minimum that has to be configured.
To configure a console application, the style is practically the same. There is no difference apart from inheriting from a different base class and starting the application in the Main() method rather than in the Global.asax.cs file.
public class ServiceAppHost : AppHostHttpListenerBase { public ServiceAppHost() : base("Order Management System", typeof (ServiceAppHost).Assembly) { }
public override void Configure(Container container) { } } static void Main() { ServiceAppHost appHost = new ServiceAppHost(); appHost.Init(); appHost.Start("http://*:80/"); Console.Read(); } |
Historically, there are several ways in which the web service can be created. Interfaces used in earlier versions of ServiceStack used IRestService and IService<T>. However, currently the recommended way is to use ServiceStack.ServiceInterface.Service, which is the approach used in this book.
public class OrderService : ServiceStack.ServiceInterface.Service { } |
As shown in the following code, the Service base class implements and exposes several very useful methods and properties such as Request and Response, which are the two most used objects in the service and give a great deal of manipulation and inspection possibilities.
public class Service : IService, IRequiresRequestContext, IServiceBase, IResolver, IDisposable { public virtual IResolver GetResolver(); public virtual IAppHost GetAppHost(); public virtual Service SetResolver(IResolver resolver); public virtual T TryResolve<T>(); public virtual T ResolveService<T>(); protected virtual TUserSession SessionAs<TUserSession>(); public virtual void PublishMessage<T>(T message); public IRequestContext RequestContext { get; set; } protected virtual IHttpRequest Request { get; } protected virtual IHttpResponse Response { get; } public virtual ICacheClient Cache { get; } public virtual IDbConnection Db { get; } public virtual IRedisClient Redis { get; } public virtual IMessageProducer MessageProducer { get; } public virtual ISessionFactory SessionFactory { get; } public virtual ISession Session { get; } } |
Request implements the .NET built-in IHttpRequest interface and therefore exposes all that we might need to know about the current request. Among the other things to note is the ability to inspect Headers, QueryString, and the current HttpMethod.
Imagine the following HTTP request.
GET http://<servername>/orders?page=1 Accept: application/json |
In the service, we can easily retrieve all of the information.
public class OrderService : ServiceStack.ServiceInterface.Service { public object Get(GetOrdersRequest request) { //value = 1 var pageQueryStringValue = this.Request.QueryString["page"]; //value = application/json var acceptHeaderValue = this.Request.Headers["Accept"]; //value = GET var httpMethod = this.Request.HttpMethod; return null; } } |
Response represents the object that the client will eventually receive. Among others, one of the most useful methods exposed by the Response object is the AddHeader method, which manipulates the headers returned to the client. Let’s look at an example of the AddHeader usage.
The following code shows the Result returned to the client.
HTTP/1.1 200 OK Cache-Control: private Content-Type: application/json Location: http://<servername>/orders Date: Sun, 28 Jul 2013 22:45:42 GMT |
A web service method can return one of the following:
The following two methods both produce the same result.
public class OrderService : ServiceStack.ServiceInterface.Service { public List<GetOrderResponse> Get(GetOrdersRequest request) { return new List<GetOrderResponse>(); } public HttpResult Get(GetOrdersRequest request) { return new HttpResult(response: new List<GetOrderResponse>(), contentType: "application/json", statusCode: HttpStatusCode.OK); } } |
The ServiceStack framework virtually supports all of the available HTTP methods. The web service method to be executed will be determined at run time by combining the routes and requested HTTP method. ServiceStack will execute a method of the service that corresponds to the actual HTTP method name. The HTTP verb GET will be executed by Get(), POST will be executed by Post(), and so on.
The following table contains some reminders about the basic HTTP verbs, what they do, and when they are used.
GET |
|
POST |
|
PUT |
|
DELETE |
|
PATCH |
|
The service can have the same HTTP verb implemented multiple times, but the input parameters should be different as with any other normal method overload.
public class OrderService : ServiceStack.ServiceInterface.Service { public object Get (SomeRequest request) {...} public object Get (SomeRequest2 request) {...} public object Post (SomePostRequest request) {...} public object Post (SomePostRequest2 request) {...} } |
If not specified otherwise, ServiceStack offers mainly three ways of negotiating the content type of the resource:
Use of the HTTP Accept header is considered by many to be a recommended and more elegant way of negotioating the content type, and it is the HTTP standard. However, it’s a hot topic and there is debate about whether to pass the format instructions directly in the URI. I think that it is good to have them both, as both have their pros and cons.
Since you should already be familiar with how to use the HTTP Accept[6] header, we won’t go into details. The following table shows the options available in ServiceStack.
Query String Style | File Extension Style | Accept Header |
…/orders?format=json | …/orders.json | Accept: application/json |
…/orders?format=xml | …/orders.xml | Accept: application/xml |
…/orders?format=jsv | …/orders.jsv | Accept: application/jsv |
…/orders?format=csv | …/orders.csv | Accept: application/csv |
Tip: It’s possible to disable the file extension style by setting Config.AllowRouteContentTypeExtensions = false in the AppHost instance.
There are different ways of defining the response content type:
public class ServiceAppHost : AppHostBase { public ServiceAppHost() : base("Order Management", typeof(ServiceAppHost).Assembly) { base.Config.DefaultContentType = ContentType.Json; } } |
Or, alternatively:
public object Get(GetOrdersRequest request) { base.Response.ContentType = ContentType.Json; return /*..*/ } |
public object Get(GetOrdersRequest request) { return new HttpResult(responseDTO, ContentType.Json); |
Routing is the process of selecting paths along which to send a request. To determine which action to perform for a request, ServiceStack has to keep the list of routes and this has to be instructed specifically when the application starts. There are several ways in which the route can be registered:
By default, for every Request DTO, ServiceStack will create a default route in the following form:
/api?/[xml|json|html|jsv|csv]/[reply|oneway]/[servicename]
Let’s suppose we want to support a custom route, http://<servername>/orders, and we expose a Request DTO called GetOrders. In this case, without specifying any route, ServiceStack will create http://<servername>/xml/reply/GetOrders automatically.
A route can be declared as a class attribute directly at the Request DTO level or in the AppHostBase by using the Fluent API. The route has an option to define one or more HTTP verbs.
By using the RouteAttribute, a route can be declared directly at the Request DTO object.
[Route("/orders", "GET POST", Notes="…", Summary="…")] public class GetOrders { } |
Instead of using the RouteAttribute, the same can be achieved by defining the route in the application host declaration.
public class ServiceAppHost : AppHostBase { public ServiceAppHost() : base("Order Management", typeof(ServiceAppHost).Assembly) { Routes .Add<GetOrders>("/orders", "GET") .Add<CreateOrder>("/orders", "POST") .Add<GetOrder>("/orders/{Id}", "GET") .Add<UpdateOrder>("/orders/{Id}", "PUT") .Add<DeleteOrder>("/orders/{Id}", "DELETE") } } |
ServiceStack’s routing mechanism offers a way to dynamically bind the parameters sent in the URL and to deserialize the object once it reaches the service. In the following code example, we can see that in the route there is an {Id} declaration. At run time, the value sent as {Id} will be deserialized as the GetOrder.Id property.
By using the Routes.AddFromAssembly(typeof(OrderService).Assembly) method, we can automatically map and define all routes.
using ServiceStack.ServiceInterface; //Request DTO (notice there is no route defined as the Attribute!) public class GetOrderRequest { public string Id { get; set; } } // Service public class OrderService : ServiceStack.ServiceInterface.Service { public List<OrderResponse> Get(GetOrdersRequest request) { … } public object Post(CreateOrder request) { … } } // Autoregistering the routes in the application host. public class ServiceAppHost : AppHostBase { public ServiceAppHost (): base("Order Management", typeof(OrderService).Assembly) { Routes.AddFromAssembly(typeof (OrderService).Assembly); } } |
By using reflection, ServiceStack will check the OrderService, determine the request’s parameter type, and autogenerate the route.
For the previous code example, the route generated will be /GetOrders (GET) and /CreateOrder (PUT).
There is a way to define a wildcard in the route; this is especially useful when the route becomes too complex.
The following is an example with a route that uses a wildcard.
Routes.Add("/orders/{CreationDate}//{Others*}", "GET"); |
In this case, the request would be /orders/2012-11-12/SomeOther/InfoGoes/Here.
This will be translated and deserialized as follows.
CreationDate = 2012-11-12; Others = “SomeOther/InfoGoes/Here”
So, the Others keyword will be taken as it is, and it can then be further processed in the application code.
My personal preference is to use the AppHost as the only place where all the paths should be declared. While there is nothing wrong with using the the RouteAttribute, I like to have all of the routes declared together in one place.
If the Request and Response DTOs POCO objects are placed in one assembly, it can be distributed without any external dependency to the clients. If using the RouteAttribute in this case, it would mean that ServiceStack libraries would need to be included as a dependency and shipped together to the client.
ServiceStack has built-in support for dependency injection. To achieve this, it uses a slightly modified version of the Funq[7] framework. Funq is fast and easy to use. ServiceStack has enhanced the basic version of Funq with lifetime scope of the injected objects and therefore supports:
All of the configuration can be done directly in the application host and declaring the objects is not very different than in any other framework.
References will be automatically injected if the service exposes a public property or if it has a constructor, with the parameters being one of the registered IoC types.
public class OrderService : ServiceStack.ServiceInterface.Service { public IOrderRepository OrderRepository { get; set; } public OrderService(IProductRepository productRepository){ /*..*/} } |
ServiceStack enables the integration of third-party IoC frameworks through the IContainerAdapter interface. This only exposes two methods.
public interface IContainerAdapter { T Resolve<T>(); T TryResolve<T>(); } |
There are several implementations already available for Microsoft Unity[8], Ninject[9], StructureMap[10], Castle Windsor,[11] and Autofac[12].
Microsoft Unity Container Adapter installation package:
PM> Install-Package ServiceStack.ContainerAdapter.Unity |
Ninject Container Adapter installation package:
PM> Install-Package ServiceStack.ContainerAdapter.Ninject |
ServiceStack has a validation framework built around the Fluent Validation library.[13]
When the validation is enabled, the validation framework will check the predefined rules before the service method gets invoked. In the case of a validation error, the ErrorResponse object will be returned with the error details (as shown in Figure 4). It’s good to know that the validation is performed on the server side.

To enable the validation, only two operations are needed:
In the following code example, the validator would only be used in the case of GET or POST methods, and this is defined with the RuleSet method. RuleFor instead specifies the rule to be applied for a given DTO property. As you will see, a customized error message can be specified.
In case of an invalid request, such as GET/orders/1, the framework will return the following error (in cases where the format specified is XML).
<ErrorResponse> <ResponseStatus> <ErrorCode>GreaterThan</ErrorCode> <Message>OrderID has to be greater than 2</Message> <StackTrace i:nil="true" /> <Errors> <ResponseError> <ErrorCode>GreaterThan</ErrorCode> <FieldName>Id</FieldName> <Message>'Id' must be greater than '2'.</Message> </ResponseError> </Errors> </ResponseStatus> </ErrorResponse> |
Since ServiceStack exposes standard RESTful web services which are based on pure HTTP, any HTTP-capable client is able to access and consume it. It doesn’t matter which programming language or framework is used; the important thing is the ability to enable communication by using HTTP.
There are several .NET clients currently available: RestSharp,[14] which is an open-source implementation, and several built-in Microsoft .NET ones like HttpClient,[15] WebClient,[16] and HttpWebRequest.[17]
The ServiceStack framework, however, provides its own client implementations that are highly optimized for ServiceStack (e.g., exception handling and routing). There are different implementations of the client, which can be a generic C# client, Silverlight client, JavaScript client, Dart[18] client, or MQ client.[19]
Clients are optimized for the content type. So there is a JsonServiceClient, XmlServiceClient, JsvServiceClient, and two SOAP clients, Soap12ServiceClient and Soap11ServiceClient, for the two current SOAP versions. The difference between the clients is the serializer/deserializer being used. As the following example shows, using a ServiceStack client is relatively easy.
JsonServiceClient client = new JsonServiceClient("http://localhost:50712/"); OrderResponse order = client.Get<OrderResponse>("/orders/1"); |
By default, when accessing the web application, ServiceStack exposes a metadata page. The metadata page contains information about the operations, available content types, Web Services Description Language (WSDL), and other objects exposed in the current application host. It is extremely useful because it acts as documentation for the available operations and used types (see Figure 5).
For every format (XML, JSON, etc.) there is an example of an input and output object. This means that we can see what the service accepts as the Request and Response DTOs.

The page is enabled by default. It is available at http://<servername>/metadata, and can be disabled by placing the following code in the application host’s Configure method.
SetConfig(new EndpointHostConfig { EnableFeatures = Feature.All.Remove(Feature.Metadata) }); |