This tutorial will go through and develop and call a simple Hello world Web Service from scratch using Service Stack and VS.NET.
If you have NuGet you can skip steps 1 - 3 below by installing one of the NuGet Host packages below:
Create an empty ASP.NET Web Application and
PM> Install-Package ServiceStack.Host.AspNet
Create an empty ASP.NET MVC Web Application and
PM> Install-Package ServiceStack.Host.Mvc
The NuGet package provides an AppHost template in your project at App_Start\AppHost.cs and some App_Start\WebServiceExamples.cs to get you started.
After looking at the README.txt - Skip the Manual Installation instructions below and start exploring ServiceStack features at:
Create a new ASP.NET Web Application by going into Visual Studio and selecting File -> New -> Project on the File menu.
Add a reference to the latest ServiceStack.dll's (or add ServiceStack dlls using NuGet) to your project:
There are 2 supported options available to register ServiceStack in your ASP.NET application Web.config:
You can host at the root path / when you don't need to use an existing Web Framework with your ServiceStack web services (i.e. project only has static files)
<system.web>
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*"/>
</httpHandlers>
</system.web>
<!-- Required for IIS 7.0 -->
<system.webServer>
<handlers>
<add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
</handlers>
</system.webServer>
In order to avoid conflicts with your existing ASP.NET web framework it is recommended to host your ServiceStack web services at a custom path.
This will allow you to use ServiceStack together with an existing web framework
e.g. ASP.NET MVC 3 or FUBU MVC, etc.
<location path="servicestack">
<system.web>
<httpHandlers>
<add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*"/>
</httpHandlers>
</system.web>
<!-- Required for IIS 7.0 -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<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>
</location>
<!-- Required for MONO -->
<system.web>
<httpHandlers>
<add path="servicestack*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*"/>
</httpHandlers>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
Note: due to limitations in IIS 6 - the /custompath must end with .ashx, e.g: path="servicestack.ashx"
To avoid conflicts with ASP.NET MVC add ignore rule in Global.asax RegisterRoutes method e.g: routes.IgnoreRoute ("servicestack/{*pathInfo}");
For simplicity we will add the Web Service and the start up script all in the same Global.asax.cs.
To do this Right-click on your project and go
Add -> New Item then select the Global Application class.
Within the same file add the following code:
public class Hello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
public class HelloService : IService<Hello>
{
public object Execute(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
public class Global : System.Web.HttpApplication
{
public class HelloAppHost : AppHostBase
{
//Tell Service Stack the name of your application and where to find your web services
public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }
public override void Configure(Container container)
{
//register user-defined REST-ful urls
Routes
.Add<Hello>("/hello")
.Add<Hello>("/hello/{Name}");
}
}
//Initialize your application singleton
protected void Application_Start(object sender, EventArgs e)
{
new HelloAppHost().Init();
}
}
Done! You now have a working application :)
Now that you have a working Web Service lets see what ServiceStack does for you out of the box:
If everything is configured correctly you can go to the /servicestack/metadata to see a list of your web services and the various end points its available on.
The Metadata page contains:
Without any configuration required, your web services are callable via the following endpoints, formats and calling convetions.
Accessible via any REST-ful urls defined using the [RestService] Attribute. e.g. in this case:
CONTENT TYPE | HTTP GET | HTTP POST CONTENT TYPE | HTTP POST FORM DATA |
---|---|---|---|
XML | /servicestack/xml/syncreply/Hello?Name=World | /servicestack/xml/syncreply/Hello | |
JSON | /servicestack/json/syncreply/Hello?Name=World | /servicestack/json/syncreply/Hello | |
HTML | /servicestack/html/syncreply/Hello?Name=World | /servicestack/html/syncreply/Hello | |
JSV | /servicestack/jsv/syncreply/Hello?Name=World | /servicestack/jsv/syncreply/Hello | |
CSV | /servicestack/csv/syncreply/Hello?Name=World | /servicestack/csv/syncreply/Hello |
The endpoint type and resulting serialization format of your web service.
The url to call your web service using only the url and the query string to populate the request.
NOTE: Service Stack also lets you submit any arbitary complex type (using JSV format) via the query string or form data: see this example.
You can HTTP POST the 'Content Type' representation of the Request DTO to the same url. Check the links to the metadata page for examples of this.
As an alternative to posting the Content Type, each service also accepts x-www-form-urlencoded Content-Types allowing you to call each web service using a HTML FORM. Here is the HTML for the live examples:
<form action="servicestack/xml/syncreply/Hello" method="post">
<label>Name:</label>
<input type="text" name="Name" value="World!">
<input type="submit">
</form>
SOAP VERSION | WSDL + END POINTS | SOAP EXAMPLE |
---|---|---|
SOAP 1.1 | /servicestack/soap11 | soap11/metadata?op=Hello |
SOAP 1.2 | /servicestack/soap12 | soap12/metadata?op=Hello |
A HTTP GET on the url returns the WSDL, while HTTP POST-ing a SOAP Request calls the web service.
Shows example of what a SOAP Request looks like.
A new addition to Service Stack is the ability to define your own custom urls letting you expose your web services via REST-ful urls.
Defining user-defined REST-ful urls can be done in one of two ways:
e.g: the following mapping:
Allows this web service to be called with: /servicestack/hello/World!
Just like the other endpoints, REST-ful urls can also be called with a HTML FORM POST. However in this case we need to define another mapping so it matches the url that we want, i.e.
Which lets us now call this web service using the following HTML:
<form action="servicestack/hello" method="post">
<label>Name:</label>
<input type="text" name="Name" value="World!">
<input type="submit">
</form>
Example:
This makes it very easy to Ajax-ify your existing HTML forms, cleanly, without messy configuration and generated code mandated by other options.
Using DTOs to define your web service interface makes it possible to provide strong-typed generic service clients without any code-gen or extra build-steps, leading to a productive end-to-end type-safe communication gateway from client to server.
All REST and ServiceClients share the same interfaces so they can easily be replaced (for increased perf/debuggability/etc) with a single line of code as seen in the Hello Service Integration tests.
C#/.NET Clients can call the above Hello Service using any of the JSON, JSV, XML or SOAP Service Clients with the code below:
var response = client.Send<HelloResponse>(new Hello { Name = "World!" });
Console.WriteLine(response.Result); // => Hello, World
client.SendAsync<HelloResponse>(new Hello { Name = "World!" },
r => Console.WriteLine(r.Result), (r, ex) => { throw ex; });
The Service Clients use the automatic Pre-Defined Routes above.
In addition, the Service Clients also provide HTTP Verbs (Get, Post & PostFile, Put, Delete) letting you call custom user-defined routes REST-fully e.g:
var response = client.Get<HelloResponse>("/hello/World!");
Console.WriteLine(response.Result); // => Hello, World
client.GetAsync<HelloResponse>("/hello/World!",
r => Console.WriteLine(r.Result), (r, ex) => { throw ex; });
Due to iOS's No-JIT restrictions, MonoTouch apps will need to use these custom builds of ServiceStack's Serializers and Service Clients.
As ServiceStack returns 'clean responses' (i.e. your Serialized DTOs as-is), it can easily be called with other existing Http or Ajax clients, e.g. using jQuery:
$.getJSON('servicestack/hello/World!', function(r){
alert(r.Result);
});
Now that you've got the hang of how easy it is to create a simple web service, check out the Northwind Database examples to see how useful servicestack becomes with just a little db code.
Hopefully this tutorial shows just how easy it is to get started and quickly build web services with Service Stack.
The complete source code for this example is viewable online or available to download as zip package from the link below: