Dinosaurs and Spaceships: Using self hosted WebAPI 2 with legacy applications


My pal has been working on a WinForms application for a couple of years, making continuous improvements and adding modules and features into it. He recently approached me with a problem. He wanted to introduce some middleware into his application and make it scale, but still perform very well. He was interested in WebApi and did not want to destroy his years of investment in developing a completely new application. His latest application has been using EntityFramework code first, that made it simpler for me to suggest a solution. He had written his application with no clear separation of concerns in VB.NET. He wanted the application to have the following structure.



I sent him the sample which uses cutting edge stuff for the middleware and WinForms client. I took advantage of the OWIN (Open Web Interface) package available on nuget.org.

To make things simple I created a shared model assembly which is shared between the server(middleware) and client. This would enable strong typing of objects from clients and server.


Creating the Server application

I developed a Console application and added the “Microsoft ASP.NET WebAPI OWIN Self Host” nuget package. I then added the code on the program as shown below. I suggest running it as a Windows Service to avoid faults when administrators close the window.


I then added the following code to start the self hosted instance of OWIN. the configuration details are in the Startup class which give routing information to the server. Simple Smile

using System;
using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Web.Http;
 using Microsoft.Owin.Hosting;
 using Owin;

namespace Dinosaur.Server
     class Program
         static void Main(string[] args)
             const string baseAddress = "http://localhost:9000/";
             using (WebApp.Start<Startup>(url: baseAddress))
                 Console.WriteLine("Press Enter to Exit");

    public class Startup
         // This code configures Web API. The Startup class is specified as a type
         // parameter in the WebApp.Start method.
         public void Configuration(IAppBuilder appBuilder)
             // Configure Web API for self-host. 
             var config = new HttpConfiguration();
                 name: "DefaultApi",
                 routeTemplate: "api/{controller}/{id}",
                 defaults: new { id = RouteParameter.Optional }


I then added a folder on the server which I called API, which would contain the API controllers. These would be served and accessible in a RESTful manner from the client application. This would make it possible to access and manipulate data using many different form factors including smartphones and tablets. The structure would be as follows.




The WebAPI controllers are very powerful and make developing APIs a piece of cake. Some of the features include content negotiation, OData, Model Binding, Filters among others.

The sample ApiController I included is as follows


    public class PersonController : ApiController
        private readonly DinosaurContext dataContext = new DinosaurContext();

        // GET api/person    
        public IEnumerable<Person> Get()
            return dataContext.People.Include("Country");

        // GET api/person/5 
        public Country Get(int id)
            return dataContext.Countries.Include("Country").SingleOrDefault(d => d.Id == id);

        // POST api/person 
        public void Post([FromBody]Person value)

        // PUT api/person/5 
        public void Put(int id, [FromBody]Person value)


        // DELETE api/person/5 
        public void Delete(int id)
            var value = dataContext.People.SingleOrDefault(d => d.Id == id);


Client Application

As mentioned before, the client application had been written in VB.NET. This is a very interesting aspect of service applications. They can be written in different languages. The server in our case is in C# while the client is in VB.NET. The client could have been in any other language that speaks HTTP. e.g. Java, PHP or Python.

In constructing the solution sample, I first added a Singleton class which I would use to access the server. I also included some directive to make more thread safe since it would be used in the Task pattern.

  1. Added the nuget package “Microsoft ASP.NET Web API Client Libraries”
  2. Added "System.Runtime.Serialization" to the forms which will have access to the server


Imports System.Net.Http

Public NotInheritable Class MainServer
     Private ReadOnly _client As New HttpClient
     Public Const BaseAddress = "http://localhost:9000/"
     Private Shared ReadOnly _instance As New Lazy(Of MainServer)(Function() New MainServer(),

    Private Sub New()

    End Sub

    Public Shared ReadOnly Property Instance() As MainServer
             Return _instance.Value
         End Get
     End Property

    Public ReadOnly Property Client() As HttpClient
             Return _client
         End Get
     End Property

End Class

I then added a class to enable serialization and deserialization of objects to and from JSON. Each time we need to save an object we first convert it into JSON and then send it over the wire through a web request. The server will take the JSON data and convert it back to an object and bind it to the receiving action method. The web request result is sent from server to inform the client on success or failure. 

Imports System.IO
Imports System.Runtime.Serialization.Json
Imports System.Text

Public Class JsonConvert
     Public Shared Function Deserialize(Of T)(json As String) As T
         Dim _Bytes = Encoding.Unicode.GetBytes(json)
         Using _Stream As New MemoryStream(_Bytes)
             Dim _Serializer = New DataContractJsonSerializer(GetType(T))
             Return DirectCast(_Serializer.ReadObject(_Stream), T)
         End Using
     End Function

    Public Shared Function Serialize(instance As Object) As String
         Using _Stream As New MemoryStream()
             Dim _Serializer = New DataContractJsonSerializer(instance.[GetType]())
             _Serializer.WriteObject(_Stream, instance)
             _Stream.Position = 0
             Using _Reader As New StreamReader(_Stream)
                 Return _Reader.ReadToEnd()
             End Using
         End Using
     End Function
 End Class


This is how I’d access the data from the server.


ReadOnly _client As HttpClient = MainServer.Instance.Client()
ReadOnly _countries = _client.GetAsync(MainServer.BaseAddress + "api/country").Result()
'Load data
cboCountry.DataSource = JsonConvert.Deserialize(Of List(Of Country))
Await _client.PostAsJsonAsync(MainServer.BaseAddress + "api/person", person).
ContinueWith(Function(postTask) postTask.Result.EnsureSuccessStatusCode())



The full solution is on github. You may download it and play around with it.



For more information about OWIN, please see

Another OWIN sample

Comments (7)
  1. Jessica Smith says:

    Thanks for sharing…

    with regards

    <a href="b2bemaillistz.com/">B2B Email Listz</a>

  2. Jessica Smith says:

    Thanks for sharing…

    with regards


  3. Joe says:

    What's the point of OWIN here?  What benefit does it offer that building a self-hosted webapi application that runs as a windows service doesn't already offer?  I've yet to find any definitive reason as to why a selfhosted webapi needs to run in OWIN, as dictated by our architects here at work.

  4. jeniffer says:

    well thnx for sharing its really beneficial

  5. Raj says:

    Thanks for sharing this. But as Joe pointed out, I'm not seeing any advantage of hosting the web api in OWIN unless I'm missing something. We can achieve the same result by using HttpSelfHostServer and HttpSelfHostConfiguration to set up the API routes.

  6. BK says:

    Raj, in the short term you could have some valid arguments.  But consider the changing tide with regards to virtualization, cloud and other technologies.  MVC6 will be a huge shift (e.g., no System.Web) and the "componentization" of the web seems to be growing… advantages are subjective and depends on who's looking at it…

  7. Derek says:

    Nice tutorial. Very concise.

Comments are closed.

Skip to main content