My adventures with OWIN and Razor

My adventures with OWIN and Razor

10 June 2014

From my experience there is no easy way to bring in the elegant ASP.NET MVC features, such as controller and view conventions, directly into OWIN/Katana.
OWIN/Katana is great for a Web API solution and as a hybrid model (using MVC 5) to bring in some Middle-ware security features.

If you're looking for server side MVC with Razor I suggest reviewing MVC 4 (.NET 4) or MVC 5(.NET 4.5) if you wish to stick with ASP.NET.
ASP.NET vNext will unify ASP.NET MVC and Web API but brings a whole ecosystem of changes to the JIT, the CLR and a new K Version Manager (KVM) which requires a some investment of time and is potential risky at this time.

OWIN (Open Web Interface for .NET) is the latest in Microsoft offering which I think is awesome.
It defines an abstraction between .NET web servers and web applications.

The first thing I tried to do was create an MVC style application using the Razor engine mixing with Web API which was a challenge. This is not as elegant as MVC 5 Views and Controllers conventions but still is possible. OWIN is geared towards creating Web API's which could be consumed by Single Page Applications for example.

Here is my code.

Startup class

This is my start-up class. I’m actually loading the views from embedded resources.

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new ApiConfiguration();
        app.UseWebApi(config);

        app.Map("", c => c.Run(context => MapView(context, "Index")));         
    }

    private Task MapView(IOwinContext context, string name)
    {
        var template = LoadStream("Index");
        var result = Razor.Parse(template);
        return context.Response.WriteAsync(result);
    }

    private static string LoadStream(string name)
    {
        using (var stream = Assembly
                .GetExecutingAssembly()
                .GetManifestResourceStream(string.Format("CHWilliamson.Host.Views.{0}.cshtml",name)))
        using (var reader = new StreamReader(stream))
        {
            return reader.ReadToEnd();
        }
    }

    public class ApiConfiguration : HttpConfiguration
    {
        public ApiConfiguration()
        {
            ConfigureRoutes();
            ConfigureJsonSerialization();
        }

        private void ConfigureRoutes()
        {
           Routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional }
           );

        }

        private void ConfigureJsonSerialization()
        {
            var jsonSettings = Formatters.JsonFormatter.SerializerSettings;
            jsonSettings.Formatting = Formatting.Indented;
            jsonSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        }
    }
}

Self Host in Console Application

You can self host this class in a console application like so:

public class Program
{
    static void Main(string[] args)
    {
        using (WebApp.Start<Startup>("http://localhost:12345"))
        {
            Console.ReadLine();
        }
    }

}

Host in IIS

If you want to host in IIS you should host your application using integrated pipeline mode. This is a setting on the Application Pool.

Ensure that your web application is referencing the Microsoft.Owin.Host.SystemWeb package. This package tethers to the IIS pipeline via a module which hunts for a class called Startup by convention.
This loading is a feature of the integrated pipeline which discovers modules.

.NET CSharp Frameworks OWIN