The future is now – OWIN and multi-hosting ASP.NET web applications

Β· 857 words Β· 5 minutes to read

As you probably know, the ASP.NET team is publishing the latest ASP.NET Web API on a nightly MyGet feed, and you can grab them from there and play with the latest stuff without having to deal with all the hassle related to building from the source.

The same applies to Katana, a Microsoft generic Owin host, which also has its own MyGet nightly feed.

Let’s glimpse into the near future and have a look at putting the latest Katana bits to play with ASP.NET Web API and other frameworks.

Intro to Owin and Katana πŸ”—

This post is not intended to be a basic introduction into Owin or Katana; there are plenty other good resources on the web about that.

Paul Glavich has recently written a great post about getting started with Owin and Katana. Yesterday, Tugberk Ugurlu followed that with another very cool introductory post.

Darrel Miller wrote a nice post on experimenting with Katana, and even on this blog, we have looked into Owin hosting before.

You can learn more here too:

If I am not mistaken, Katana project is now owned by MS Open Tech, and has some extremely smart people involved in it, such as Louis DeJardin, Chris Ross or Howard Dierking, just to mention a few.

Pulling the latest bits πŸ”—

You can grab the latest bits from the following nightly feeds:

For this sample we will not even need the Katana.exe itself, we’ll use the Katana feed to get the latest version of the Microsoft.Owin.Hosting package hosted there (the Katana DLL).

Configuring the solution πŸ”—

Let’s start a new console project and add the following packages.config:

<?xml version="1.0" encoding="utf-8"?> <packages> <package id="Microsoft.AspNet.SignalR.Core" version="2.0.0-beta1-130501" targetFramework="net45" /> <package id="Microsoft.AspNet.SignalR.Owin" version="2.0.0-beta1-130501" targetFramework="net45" /> <package id="Microsoft.AspNet.WebApi.Client" version="5.0.0-alpha-130501" targetFramework="net45" /> <package id="Microsoft.AspNet.WebApi.Core" version="5.0.0-alpha-130501" targetFramework="net45" /> <package id="Microsoft.AspNet.WebApi.OwinHost" version="5.0.0-alpha-130501" targetFramework="net45" /> <package id="Microsoft.Owin" version="1.1.0-beta-20501-263" targetFramework="net45" /> <package id="Microsoft.Owin.Host.HttpListener" version="1.1.0-alpha1-20430-258" targetFramework="net45" /> <package id="Microsoft.Owin.Hosting" version="1.1.0-beta-20501-263" targetFramework="net45" /> <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" /> <package id="Owin" version="1.0" targetFramework="net45" /> </packages> ```

This will install the latest ASP.NET Web API bits (version 5), latest SignalR bits (version 2) and the latest Microsoft Owin host. Latest versions of Web API and SignalR both rely on Owin middledware.

Let's also throw in Nancy there, to illustrate how different frameworks can play together nicely with Owin:

```xml<package id="Nancy" version="0.17.1" targetFramework="net45" /> <package id="Nancy.Owin" version="0.17.1" targetFramework="net45" /> ```

### Multi-hosting self host

One of the most exciting features Owin enables, is the multi-hosting self host mode. Most of the .NET web frameworks allow you to perform some sort of self hosting (to avoid IIS). This is normally based on _HttpListener_ and normally requires a dedicated port (a.k.a "port cannibalizing").

With Owin, these frameworks delegate the ownership of the HTTP listener to the underlying Owin host, in this case, Katana.

Owin supports multi hosting through _host.Addresses_ configuration key:


```csharp 
var addresses = new List<IDictionary<string, object>>();  
addresses.Add(new Dictionary<string, object>  
{  
{ "scheme", scheme },  
{ "host", host },  
{ "port", port },  
{ "path", path }  
});  

Pretty much all Owin configuration is done through such lists of dictionarieis, and of course working with dictionaries is hardly desirable for everyday development tasks, therefore each of the frameworks provides an Owin adapter - such as the ones we used in our packages.config:

    • Microsoft.AspNet.SignalR.Owin
    • Microsoft.AspNet.WebApi.OwinHost
    • Nancy.Owin

The also normally provide OwinExtensions methods allowing for easy registration of a given framework against the Owin host.

With these in place we can now configure multi hosting very easily:

class Program  
{  
static void Main(string[] args)  
{  
var options = new StartOptions();  
options.Urls.Add("http://localhost:999/");  
using (WebApp.Start(options, builder =>  
{  
var config = new HttpConfiguration();  
config.Routes.MapHttpRoute("Default", "api/{controller}/{id}", new {id = RouteParameter.Optional});

builder.Properties["host.AppName"] = "filip app";  
builder.UseWebApi(config);  
builder.MapHubs("signalr", new HubConfiguration  
{  
EnableCrossDomain = true,  
EnableJavaScriptProxies = true,  
Resolver = new DefaultDependencyResolver()  
});

builder.UseNancy();  
}))  
{  
Console.ReadKey();  
}  
}  
}  

In this case, we have created a Web API config, and instructed Owin IAppBuilder to use it. We also registered SignalR hubs and Nancy against the same IAppBuilder - which will sit on port 999.

Note, this line

builder.Properties["host.AppName"] = "filip app";  

shouldn’t be requried, but I ran into some issues that where it wasn’t set, SignalR was throwing null reference, but I’m guessing this will be fixed sooner or later.

With such set we now have:

  • Nancy at http://localhost:999/
  • Web API at http://localhost:999/api
  • Signalr at http://localhost:999/signalr

Let’s throw in some basic classes related to these frameworks - a SignalR hub, Web API controller and a Nancy module:

[HubName("hellohub")]  
public class MyHub : Hub  
{  
public void Send(string message)  
{  
Clients.All.addMessage(message);  
}  
}

public class IndexModule : NancyModule  
{  
public IndexModule()  
{  
Get["/"] = x =>  
{  
return "Hello Nancy!";  
};  
}  
}

public class TestController : ApiController  
{  
public string Get()  
{  
return "Hello Web Api";  
}  
}  

We can now run our solution and voila! Everything running side by side, in perfect harmony!

And SignalR:

Owin support is coming in the future release of Web API, and soon we will all be doing ASP.NET development with server and application being completely decoupled through the use of Owin! The potential here is amazing!

About


Hi! I'm Filip W., a software architect from ZΓΌrich πŸ‡¨πŸ‡­. I like Toronto Maple Leafs πŸ‡¨πŸ‡¦, Rancid and quantum computing. Oh, and I love the Lowlands 🏴󠁧󠁒󠁳󠁣󠁴󠁿.

You can find me on Github, on Mastodon and on Bluesky.

My Introduction to Quantum Computing with Q# and QDK book
Microsoft MVP