OWIN and Katana part 4: Web API on top of OWIN

Introduction

In the previous post in this series we wrote a couple of OWIN middleware components and chained them together. We actually achieved quite a lot in a low level console application: it hosts a simple web server which receives HTTP requests, it processes the requests with Katana components and performs some elementary logging.

It’s now time to build an application on top of this environment. We’ll build upon the demo console app we’ve been working on so have it ready in Visual Studio. If you’ve read some other topics on this blog then you’ll note that I have a preference for the Web API as the server platform. So let’s see how we can build a Web API application on top of our little server.

Web API demo

Open the Console demo server in Visual Studio. We’ll need to install the following NuGet package:

Web API Owin Selfhost

As the package name implies this package will help us host a Web API 2.1 app using OWIN components. The package installs a number of other components such as WebApi.Core WebApi.Client, JSON.NET, etc. Open the References section in the Solution Explorer. If you’ve worked with the Web API before then some of those new libraries will be familiar to you: System.Net.Http, System.Web.Http and the like.

Add the following class to the project:

public class LatestNews
{
	public string Summary { get; set; }
}

We want our web service to show the latest news.

Let’s also add another class called LatestNewsController. It will be our first Web API controller. If you haven’t worked with the Web API before then a Web API controller has the same role as a “normal” controller in an MVC web app. It derives from the “ApiController” base class rather than the “Controller” class in MVC. The LatestNewsController class looks as follows:

public class LatestNewsController : ApiController
{
	public HttpResponseMessage Get()
	{
		LatestNews news = new LatestNews() { Summary = "The world is falling apart." };
		return Request.CreateResponse<LatestNews>(HttpStatusCode.OK, news);
	}
}

In Startup.Configuration comment out the Use method which dumps out the values in the Environment dictionary. The starting point for this exercise is the following “active” code, the rest should be commented out or removed:

public void Configuration(IAppBuilder appBuilder)
{
        appBuilder.Use(async (env, next) =>
	{
		Console.WriteLine(string.Concat("Http method: ", env.Request.Method, ", path: ", env.Request.Path));
		await next();
		Console.WriteLine(string.Concat("Response code: ", env.Response.StatusCode));
	});

	appBuilder.UseWelcomeComponent();			
}

Insert a new method stub in Startup.cs that will configure Web API:

private void RunWebApiConfiguration(IAppBuilder appBuilder)
{	
}

The key object to configuring the Web API is the HttpConfiguration object located in the System.Web.Http namespace. It opens, among a lot of other things, the gateway to the routing rules. Insert the following body to the above function:

HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.Routes.MapHttpRoute(
	name: "WebApi"
	, routeTemplate: "{controller}/{id}"
	, defaults: new { id = RouteParameter.Optional }
	);
appBuilder.UseWebApi(httpConfiguration);

This will look very familiar to you if you’ve done any MVC and/or Web API programming – which you probably have otherwise you wouldn’t be reading this post. So we set up out first routing rule using the MapHttpRoute method like in the standard Web API app template of Visual Studio. Finally we call upon the built-in extension of the IAppBuilder interface to declare that we want to use the Web API.

We should be ready to go. Add a call to this method from Configuration():

appBuilder.Use(async (env, next) =>
	{
		Console.WriteLine(string.Concat("Http method: ", env.Request.Method, ", path: ", env.Request.Path));
		await next();
		Console.WriteLine(string.Concat("Response code: ", env.Response.StatusCode));
	});

RunWebApiConfiguration(appBuilder);

appBuilder.UseWelcomeComponent();

Run the demo app and navigate to localhost:7990/latestnews in a web browser. You should see that our Web API component is indeed responding to the request:

Web Api output in web browser

We got the latest news in an XML serialised format. Also, you’ll notice that the middleware that prints the incoming request data in the console window still works:

Logging middleware still running

Now navigate to localhost:7990, i.e. without any controller name. You’ll see that our WelcomeComponent responds with “Hello from the welcome component”. The reason is that the web api component couldn’t route the request to any controller so it let the next component take over. The next component in the pipeline is the WelcomeComponent which happily responds to any request with the same message.

We have just built the basics of a self hosted Web API application which is very light weight, easy to extend and responds to incoming HTTP requests with meaningful data.

Deployment

Let’s try to deploy this application on IIS. Install the following NuGet package:

Owin host system web NuGet package

This package ensures that we can plug in our application into the ASP.NET pipeline.

We’ll also need to change a couple of other things in the application. IIS cannot directly load executables so our setup code in Program.Main is not relevant. Comment out the following chunk of code, all of it, including the Program class declaration:

class Program
    {
        static void Main(string[] args)
        {
			string uri = "http://localhost:7990";

			using (WebApp.Start<Startup>(uri))
			{
				Console.WriteLine("Web server on {0} starting.", uri);
				Console.ReadKey();
				Console.WriteLine("Web server on {0} stopping.", uri);
			}
        }
    }

All the startup infrastructure will be handled by IIS. However, we still want to run the Configuration code in Startup.cs. Open the project properties and turn the project type into a class library:

Turn console app into class library

Also, change the output path to simply ‘bin’ as is expected by IIS:

Change output path to bin

Build the solution to make sure it still compiles without errors. Check in the bin folder of the project that the [projectname].dll file was created by the build process. I called my project KatanaBasics so I have a KatanaBasics.dll in the bin folder. You’ll need the path to the bin folder in the next step.

We’ll use the iisexpress.exe file to load our this dll. The iisexpress.exe file is usually found here:

IISexpress.exe location

Open a command prompt and enter the following command. Make sure you enter the correct path as it appears on your system:

IIS express command prompt startup

…where the “path” parameter is the path to the bin folder on my computer. Press Enter and if everything goes well then you’ll see the following response:

IIS running in command prompt

You’ll notice in the output that IIS will be listening on port 8080 for this application. Navigate to localhost:8080 in a web browser and you should see that… …we get an exception, or at least I got it:

Missing owin assembly

Owin assemblies are updated quite often so it’s almost expected to run into this classic “Could not load file or assembly” error, although it’s really irritating.

Stop the IIS application by pressing “Q” in the command prompt. The solution is quite easy actually. The solution contains an app.config file with the following bit of XML:

<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />

This should do the trick of redirecting old references to an updated one. However, IIS won’t read this file as it is looking for a web.config file instead of app.config. Rename app.config to web.config. Then rebuild the solution, issue the same IIS command as before in the command prompt and navigate to localhost:8080. The WelcomeComponent should respond with “Hello from the welcome component”. Also, you should see the logging output in the command prompt along with some output from IIS itself:

Logging output with IIS running

The output of our OWIN middleware has been successfully plugged into the IIS infrastructure. Now check if the web api controller is still responding on localhost:8080/latestnews. You should see that it does indeed.

The OWIN project we’ve built produces a dll which can be referenced from any type of application: console, WPF, WCF, etc., it will always produce valid XML.

How was our application configured correctly now that the Program class has been commented out? How was our Configuration method called now that there’s no code calling it directly? The Host.SystemWeb dll has a bit of code that will look for a class called Startup and run its Configuration method for you automatically.

You can specify the location of the Startup in the appSettings section of web/app.config:

<appSettings>
	<add key="owin.appStartup" value="KatanaBasics.Startup"/>
</appSettings>

…where the value is the fully qualified name of the Startup class.

You can also specify it in the AssemblyInfo file:

[assembly: OwinStartup(typeof(KatanaBasics.Startup))]

If you don’t specify these values then it will try to find the Startup class through Reflection in the namespace matching the project name, in this case KatanaBasics. Since there’s one such class in that namespace, the web hosting process found it and executed it.

OWIN, Katana and MVC

Let’s see how OWIN and Katana are incorporated into ASP.NET MVC. In Visual Studio 2013 create a new MVC5 web application. Open the references list and you’ll see that there are several Owin related packages included by default:

Owin references in MVC5

You’ll also notice that there’s a Startup.cs in the root of the application:

Startup.cs in MVC5

Open the file and you’ll see the Configuration method which accepts an IAppBuilder object, so it follows the same pattern as we saw in our console based server app. The Configure method calls upon a method called ConfigureAuth. You’ll also notice the assembly metadata above the namespace that tells Katana where to look for the Startup class.

Note that this is a partial class so there’s one more Startup class. You’ll find it in the App_Start folder in a file called Startup.Auth.cs. This is where the ConfigureAuth method is implemented. As the method name suggests ConfigureAuth defines some OWIN middleware that have to do with authentication.

Most of the code is commented out. The two middleware functions that are not commented out are:

  • UseCookieAuthentication: to implement cookie authentication, checks if there’s a valid authentication cookie
  • UseExternalSignInCookie: for external cookies for third party auth providers

You can uncomment the rest of the code to activate either of the 4 available authentication providers: Microsoft, Twitter, Facebook and/or Google for OAuth2. We will look at these in a later series dedicated to security in MVC5.

Katana sourcecode

If you’re interested in how the Katana components are built then you can check out the sourcecode on the Katana Codeplex page. You’ll see the code for all existing Katana components there:

Katana codeplex page

You can even load the entire code from Git. You’ll find the git clone command on the Codeplex page.

View the list of MVC and Web API related posts here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

9 Responses to OWIN and Katana part 4: Web API on top of OWIN

  1. Pingback: Dev.Cast 71 – OWIN och Katana

  2. cristinapienescu says:

    Hi again Andras,

    I see that the MVC 5 app has still a reference to the old, big System.Web. Does it mean that it is still bound to IIS?

    Can an MVC5 app be hosted in a simple console app that supports OWIN (like in your ex)?

    Instead of wiring Http modules, or actions’s filters we use Katana’s App Funcs for the http request pipeline?
    thank you,
    C

    • Andras Nemes says:

      Hi Cristina,

      The standard MVC5 project is still bound to IIS. The way I see the current state of OWIN/Katana is that it’s only in an introduction phase. At present it’s only some authentication bits that are linked to OWIN from the start, the rest comes from System.Web. In the future versions of MVC this may change so that System.Web will become optional for those not willing to work with OWIN 100%.

      I think it’s possible to host a full MVC5 application building upon the example but you’ll probably have a lot of plumbing to do. LatestNewsController is an example of a controller, other controllers can follow in this fashion.

      Note that I’ve only experimented with OWIN so I’m not 100% sure how to build a full MVC site with OWIN middleware only which has the same functionality as a full-blown MVC app.

      //Andras

  3. j. brenes says:

    Thank you! This helped me getting SignalR to work:

    jb
    Florida

  4. Steve says:

    Andras, this was a really useful series about OWIN and Katana, thank you very much.

  5. Chris says:

    As of 6/2015 NuGet installs Web API 2.2OWIN Self Host. Not sure if this is why latestnews triggers a 404.

    Web service on http://localhost:7990 starting.
    Http method: GET. Path: /latestnews
    Response code: 404

    No compile-time or run-time errors are thrown in the code. Has anyone else had this happen? Any workarounds?

  6. RR says:

    Thanks for your posts. Fantastic !

  7. Philip says:

    Hi Andras, thanks for the series of post was really helpful, to the point and fluent.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT BEST PRACTICES WITH MICROSOFT STACK & ANGULAR

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: