You are on page 1of 25

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

1 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Articles Web Development ASP.NET General

ASP.NET: Understanding OWIN, Katana, and the


Middleware Pipeline
John Atten, 26 Jan 2015

CPOL

5.00 (32 votes)


The tools and architectural patterns we use to build and evolve web applications have undergone dramatic change over the past
few years. Modern web application development is a fast-paced, dynamic activity reliant to ever an greater degree on modular,
loosely-coupled application components, rapidly-

The tools and architectural patterns we use to build and evolve web
applications have undergone dramatic change over the past few
years. Modern web application development is a fast-paced,
dynamic activity reliant to ever an greater degree on modular,
loosely-coupled application components, rapidly-evolving
frameworks, and shorter development cycles.
Historically, the ASP.NET ecosystem (including Web Forms, MVC,
Web Api, SignalR, and others) sat on top of System.Web, and was
tightly coupled to the underlying .NET framework as a whole.
Further, ASP.NET web applications have been reliant on Microsoft
Internet Information Services (IIS) to provide the hosting
environment necessary to run in production.
Image by Sunova Surfboards | Some Rights Reserved

What is OWIN, and Why Do I Care?


What is Katana?
Console Application Example: Creating a Barebones Katana Application
Katana and the IAppBuilder Interface
Chaining Multiple Middlewares
Using Katana Abstractions: IOwinContext
Creating Middleware Components as Stand-Alone Classes
Add Custom Extensions for IAppBuilder
Adding Middleware Configuration Options
Requests, Responses, and Short-Circuiting the Middleware Pipeline
Create MiddleWare Components as Stand-Alone Assemblies
Consuming the Stand-Alone Components from the Sample Project
ASP.NET Web Api 2.2: Create a Self-Hosted OWIN-Based Web Api from Scratch
Additional Resources and Items of Interest
We expand upon the middleware concepts discussed here, and tie things together with ASP.NET Web API, in the next few posts:
ASP.NET Web Api 2.2: Create a Self-Hosted OWIN-Based Web Api from Scratch
ASP.NET Web Api: Understanding OWIN/Katana Authentication/Authorization Part I: Concepts

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

2 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

ASP.NET Web Api: Understanding OWIN/Katana Authentication/Authorization Part II: Models and Persistence
In the past two years, the ASP.NET team has been evolving the .NET web development ecosystem away from this approach, and
instead creating a growing set of pluggable components. Beginning with ASP.NET 4.5.1, we have seen the introduction of more
and more pluggable application components which are not dependent on System.Web, and which can be configured to run
outside the constraints of IIS using custom hosts.
My understanding is that ASP.NET 5 ("vNext") will be moving way, way further in this direction.
Understanding the relationship between the hosting process, the web server, and our application components is going to
become increasingly important as the ASP.NET ecosystem becomes more and more modular. More and more, this relationship,
and the pluggable architecture upon which our .NET web applications will depend, has been defined by the Open Web Interface
for .NET (OWIN) specification.
And we need to understand how it works in order to take full advantage of the evolving .NET Web Stack.
UPDATE 1/5/2015: ASP.NET 5 is indeed moving further in this direction. Katana itself will apparently be fully integrated into
ASP.NET 5. OWIN will be available through an interop, but greenfield projects will be best off using the integrated middleware
pipeline. The implementation details will be changing to a degree. However, most of what we discuss here will still apply, either
directly, or conceptually (thanks to Rick Anderson and the ASP.NET team for the clarification!).
We will examine the ASP.NET 5 middleware pipeline in an upcoming post.

What is OWIN, and Why Do I Care?


OWIN (the Open Web Interface for .NET) is an open-source specification describing an abstraction layer between web servers
and application components. The goal of the OWIN specification is to facilitate a simple, pluggable architecture for .NET-based
Web applications and the servers upon which they rely, encouraging development of small, focused application components
(known as "middlewares" in the OWIN parlance) which can be assembled into a processing pipeline through which the server
can then route incoming HTTP requests.
From the Owin.org About page:
"OWIN defines a standard interface between .NET web servers and web applications. The goal of the OWIN
interface is to decouple server and application, encourage the development of simple modules for .NET web
development, and, by being an open standard, stimulate the open source ecosystem of .NET web development
tools."
OWIN is a specification, not an implementation. As such, OWIN describes a minimal set of types, and a single application
delegate through which interactions between an application component and the server will occur.
Note that the OWIN specification is an open source community effort independent of Microsoft.

OWIN Definitions
OWIN provides the following general definitions for software elements in an OWIN-based application:
Server The HTTP server that directly communicates with the client and then uses OWIN semantics to process
requests. Servers may require an adapter layer that converts to OWIN semantics.
Web Framework A self-contained component on top of OWIN exposing its own object model or API that
applications may use to facilitate request processing. Web Frameworks may require an adapter layer that converts
from OWIN semantics.
Web Application A specific application, possibly built on top of a Web Framework, which is run using OWIN
compatible Servers.
Middleware Pass through components that form a pipeline between a server and application to inspect, route, or
modify request and response messages for a specific purpose.
Host The process an application and server execute inside of, primarily responsible for application startup. Some
Servers are also Hosts.

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

3 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

The OWIN Environment Dictionary


The host in an OWIN-compatible application provides an Environment Dictionary in the form of IDictionary<string,
object> containing all of the relevant information about the request, response, and server/host information. The OWIN
specification defines a minimum set of keys and values which must be present in the dictionary. However, servers, host
environments, middleware, and application code may add additional data, or modify the data in the dictionary as a result of
processing.

The OWIN Application Delegate Function


As mentioned above, OWIN also specifies a primary interface, the Application Delegate (also known as AppFunc). Interactions
between the server and application components occurs through calls to the AppFunc delegate.
An Application Delegate function will take the Environment Dictionary (IDictionary<string, object>) as an
argument, use the request/response information contained in the environment dictionary to perform whatever processing is
required to meet its responsibilities, and return a Task when processing is complete.

The Application Delegate Function Signature specified by OWIN:


Func<IDictionary<string, object>, Task>
In our code, we will often use the alias AppFunc for this delegate to improve readability:

Alias the Application Delegate for use in code:


using AppFunc = Func<IDictionary<string, object>, Task>;

The OWIN Middleware Pipeline


In keeping with the above, individual application components (middleware) perform their processing duties when the AppFunc
delgate is called. However, in order to maintain the pipeline, each middleware component is also responsible for invoking the
next component in the chain (or, intentionally NOT calling the next component and short-circuiting the chain if appropriate.

In light of this, each middleware component needs to provide an AppFunc delegate to be called in order to do its own work in
the pipeline, and also needs to receive a reference to the next AppFunc delegate, to be called (in most cases) once the current
component has completed processing.
In other words, a middleware can be expressed with a signature which accepts an AppFunc delegate as an argument (which is
retained and called as the next process in the pipeline), and which returns an AppFunc Delegate (which is used to perform the
current middleware processing:

Middleware Delegate Signature:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

4 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Func<AppFunc, AppFunc>
In code, this might look something like this:

Example Middleware as Function:


public AppFunc SomeMiddleware(AppFunc next)
{
// Create and AppFunc using a Lambda expression:
AppFunc appFunc = async (IDictionary<string, object> environment) =>
{
// Do some processing ("inbound")...
// Invoke and await the next middleware component:
await next.Invoke(environment);
// Do additional processing ("outbound")
};
return appFunc;
}
We'll see how all this works shortly.

What is Katana?
Katana is a set of open source components for building and hosting OWIN-based web applications, maintained by the Microsoft
Open Technologies Group.
Katana provides an implementation of the OWIN specification, and is in fact used in an increasing number of ASP.NET project
templates. Additionally, Katana provides a wide variety of ready-to-use middleware components, ready for use in an
OWIN-based application.
For our purposes, we will use some basic components from Katana to demonstrate and understand:
How an OWIN-based middleware pipeline is configured
How to construct a basic middleware component
How OWIN and the middleware pipeline fit into a web application generally
How all this comes together into the middleware pipeline, and the manner in which your application configures and interacts
with it can be confusing at first. For one thing, we are dealing with a lot of delegate functions and generic types. Also, there are
still some things happening behind the scenes that are not obvious at first.,
The best way to understand how OWIN, Katana, and the middleware pipeline works is, well, to jump in and mess about.

Console Application Example: Creating a Barebones Katana Application


An example of the simplicity available with an OWIN-based application is the fact that we can create a simple Console
application, pull in a few Nuget packages, and spin up a self-hosted web server. To get started, create a new console application
in visual studio. Then, add the following Nuget packages using the Package Manager Console:

Install Microsoft.Owin.Hosting via Nuget Package Manager Console:


PM> Install-Package Microsoft.Owin.Hosting
The Microsoft.Owin.Hosting package added a few library references to our project, notably Owin,

Microsoft.Owin, and of course, Microsoft.Owin.Hosting.


Next, we need to add a means for our console application to listen for HTTP requests:

Install Microsoft.Owin.Host.HttpListener via Nuget Package Manager Console:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

5 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

PM> Install-Package Microsoft.Owin.Host.HttpListener


With that, we have everything we need to put together a simple self-hosted web application.
Most of the examples we examine in this post will be overly (some might say "stupidly") simple, and let's bear in mind that we
are focusing more on how basic middleware are constructed, and how the middleware pipeline works in general than we are on
how to write specific middleware components, or how to use all of the Katana features. I stick with silly examples here so that we
are focused on the core middleware structure, and how the pipeline works, and not on complex middleware implementation
details.
First, add the following code the the Program.cs file in your application:

The basic KatanaConsole Application:


using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
System.IO;

// Add the Owin Usings:


using Owin;
using Microsoft.Owin.Hosting;
using Microsoft.Owin;
namespace KatanaConsole
{
// use an alias for the OWIN AppFunc:
using AppFunc = Func<IDictionary<string, object>, Task>;
class Program
{
static void Main(string[] args)
{
WebApp.Start<Startup>("http://localhost:8080");
Console.WriteLine("Server Started; Press enter to Quit");
Console.ReadLine();
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
var middleware = new Func<AppFunc, AppFunc>(MyMiddleWare);
app.Use(middleware);
}
public AppFunc MyMiddleWare(AppFunc next)
{
AppFunc appFunc = async (IDictionary<string, object> environment) =>
{
// Do something with the incoming request:
var response = environment["owin.ResponseBody"] as Stream;
using (var writer = new StreamWriter(response))
{
await writer.WriteAsync("<h1>Hello from My First Middleware</h1>");
}
// Call the next Middleware in the chain:
await next.Invoke(environment);
};
return appFunc;
}
}
}

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

6 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Now, let's take a look at a few items of note here. First off, we have added an alias for the Application
Delegate, so that in our code, we can refer to Func<IDictionary<string, object> , Task> by the
name AppFunc.
Next, we have added a method to the Startup class, MyMiddleware(), which accepts an argument of type AppFunc
named next, and returns and AppFunc. If we look closely, we see that the anonymous function returned by the
MyMiddleware() method, when invoked by the host against an incoming HTTP request, will perform some basic processing
against the incoming request (actually, writing to the response body), and will then invoke the AppFunc next passed in as an
argument, passing to it the environment dictionary, and thereby continuing the pipeline processing of the request.
Bear in mind that the MyMiddleware() method simply returns the anonymous function to the caller, but does not invoke it.
The function will be added the to request processing pipeline, and will be invoked when an incoming HTTP request needs to be
processed.
Most importantly, let's take a look at the Startup class.
In the Katana implementation of the OWIN specification, the host will look for a startup entry point to build the middleware
pipeline in one of four ways (in order as listed below):
The Startup class is specified as a command line argument, or a type argument (where applicable) when the host in
initialized (usually when using OwinHost, or the Owin.Hosting API, which is what we did in our code above).
The host will look in the relevant app.Config or web.Config file for an appSettings entry with the key "owin:AppStartup"
The host will scan the loaded assemblies for the OwinStartup attribute and uses the type specified in the attribute.
If all of the preceding methods fail, then the host will use reflection and scan the loaded assemblies for a type named
Startup with a method with the name and signature void Configuration(IAppBuilder).
The Startup class must provide a public Configuration() method, as mentioned above, with the signature void

Configure(IAppBuilder app).

Katana and the IAppBuilder Interface


The IAppBuilder interface is NOT a part of the OWIN specification. It is, however, a required component for a Katana host.
The IAppBuilder interface provides a core set of methods required to implement the OWIN standard, and serves as a base
for additional extension methods for implementing middleware.
When the Katana host initializes the Startup class and calls Configuration(), a concrete instance of IAppBuilder is
passed as the argument. We then use IAppBuilder to configure and add the application middleware components we need
for our application, assembling the pipeline through which incoming HTTP requests will be processed.
The most common way to add middleware is by passing components to the Use() method. Middleware components will be
added to the pipeline in the order they are passed to Use(). This is important to bear in mind as we configure our pipeline, as
this will determine the order in which processing is applied to incoming requests (and in reverse, to outgoing responses).
In our code, we grab a reference to our middleware function by calling MyMiddleware(), and then add it to the pipeline be
passing it to app.Use().

Running the Application


If we run the application, we se that our server has started:

Console output from first run of the Application:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

7 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

And, if we open a web browser and navigate to our URL, we see the expected output:

Navigate to URL in Browser:

Presto! We have created a bare-bones, self-hosted web application using only a console application, and a handful of small
Katana components.
More importantly, we have created our first OWIN middleware.
Now, let's see how the whole pipeline/chaining thing works.

Chaining Multiple Middlewares


Thus far, we have created an application with a single middleware component in the pipeline. While we properly included a
parameter in our middleware function for a "next" AppFunc to be invoke, there is nothing to work with at the moment.
Let's create a second component to add to the pipeline, and see how that works. Add another method to the Startup class in our
code below the MyMiddleware() method:

Add another Middleware function to the Startup class:


public AppFunc MyOtherMiddleWare(AppFunc next)
{
AppFunc appFunc = async (IDictionary<string, object> environment) =>
{
// Do something with the incoming request:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

8 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

var response = environment["owin.ResponseBody"] as Stream;


using (var writer = new StreamWriter(response))
{
await writer.WriteAsync("<h1>Hello from My Second Middleware</h1>");
}
// Call the next Middleware in the chain:
await next.Invoke(environment);
};
return appFunc;
}

Next, update the Configuration() method to add this new middleware:


Add the New Middleware to the Processing Pipeline in the Configure() Method:
public void Configuration(IAppBuilder app)
{
var middleware = new Func<AppFunc, AppFunc>(MyMiddleWare);
var otherMiddleware = new Func<AppFunc, AppFunc>(MyOtherMiddleWare);
app.Use(middleware);
app.Use(otherMiddleware);
}

Now, all we have done is create another middleware and add it to the pipeline by passing it to app.Use(),
similar to the first. However, if we run our application again, we see that both middlewares are executed:
Running the Application with Multiple Middlewares in the Pipeline:

Now, it would be easy to think that maybe both functions are just executing anyway, but let's see what happens when we
comment out the bit where we invoke the "next" AppFunc in our first middleware:

Comment Out Call to Invoke Next AppFunc:


public AppFunc MyMiddleWare(AppFunc next)
{
AppFunc appFunc = async (IDictionary<string, object> environment) =>
{
// Do something with the incoming request:
var response = environment["owin.ResponseBody"] as Stream;

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

9 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

using (var writer = new StreamWriter(response))


{
await writer.WriteAsync("<h1>Hello from My First Middleware</h1>");
}
// Call the next Middleware in the chain:
// await next.Invoke(environment);
};
return appFunc;
}

Refresh our browser, we see the second middleware never executed, even though is has been added to the
pipeline:
Next Middleware Fails if Next is not Invoked:

Clearly, if next is not invoked, the pipeline is short-circuited. Also, if we change the order in which we add the middlewares to the
pipeline, the processing order is affected:

Change the order Middlewares are added (and uncomment call to next):
public void Configuration(IAppBuilder app)
{
var middleware = new Func<AppFunc, AppFunc>(MyMiddleWare);
var otherMiddleware = new Func<AppFunc, AppFunc>(MyOtherMiddleWare);
// Swap the order here:
app.Use(otherMiddleware);
app.Use(middleware);
}
Refreshing the view in our browser, we should not be surprised:

Changing the Order in Which Middleware is Added to the Pipeline:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

10 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Thus far we have implemented a very basic OWIN-based Processing pipeline, using the raw types expected by the OWIN
specification. Now let's see if we can make life a little easier, using some tools provided by Katana, and by laying some
abstraction on our middlewares to make them easier to think about.

Using Katana Abstractions: IOwinContext


In our previous example, we worked with the raw Environment Dictionary as specified by OWIN. This provides a flexible,
low-level mechanism, but is less than handy when we want to work with strongly-typed objects, and perhaps raise our
abstractions up a level in our pipeline implementation code.
Katana provides us with a handy interface, IOwinContext, and a concrete wrapper for the Environment Dictionary,

OwinContext. We can use IOwinContext to access some of the information in the Environment Dictionary in a more
convenient, strongly typed manner. For example, we could modify our code like so:

Modify Middleware Code to use IOwingContext:


public AppFunc MyMiddleWare(AppFunc next)
{
AppFunc appFunc = async (IDictionary<string, object> environment) =>
{
IOwinContext context = new OwinContext(environment);
await context.Response.WriteAsync("<h1>Hello from My First Middleware</h1>");
await next.Invoke(environment);
};
return appFunc;
}
public AppFunc MyOtherMiddleWare(AppFunc next)
{
AppFunc appFunc = async (IDictionary<string, object> environment) =>
{
IOwinContext context = new OwinContext(environment);
await context.Response.WriteAsync("<h1>Hello from My Second Middleware</h1>");
await next.Invoke(environment);
};
return appFunc;
}
In fact, the IOwinContext object, and similar interfaces provided by Katana such as IOwinRequest and

IOwinResponse provide a large number of useful, strongly-typed abstractions which simplify our interaction with the
environment. These interfaces are, in fact, quite similar to the familiar HttpContext, HttpRequest, and
HttpResponse objects we are accustomed to using in a standard MVC or Web Api application.

Creating Middleware Components as Stand-Alone Classes

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

11 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

So far, we've taken the raw, bare-bones approach to creating middleware for our application, by using a method with the
signature Func<AppFunc, AppFunc> and pushing it into our pipeline. However, a more modular approach would be to
create our middleware are individual classes.
We can do this, so long as the class we create adheres to some specific requirements.
The class must have a constructor which accepts an argument of (wait for it) AppFunc, and must provide a method named
Invoke which accepts an argument of IDictionary<string,

object> and returns Task.

To continue our trivial example, we can take our two methods, MyMiddleWare()and MyOtherMiddleware() and
create classes instead:

Create Stand-Alone Middleware as Separate Classes:


public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use<MyMiddlewareComponent>();
app.Use<MyOtherMiddlewareComponent>();
}
}
public class MyMiddlewareComponent
{
AppFunc _next;
public MyMiddlewareComponent(AppFunc next)
{
_next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
IOwinContext context = new OwinContext(environment);
await context.Response.WriteAsync("<h1>Hello from My First Middleware</h1>");
await _next.Invoke(environment);
}
}
public class MyOtherMiddlewareComponent
{
AppFunc _next;
public MyOtherMiddlewareComponent(AppFunc next)
{
_next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
IOwinContext context = new OwinContext(environment);
await context.Response.WriteAsync("<h1>Hello from My Second Middleware</h1>");
await _next.Invoke(environment);
}
}
Note, we have pulled our Func<AppFunc, AppFunc> methods out and refactored them into classes. Also, we have
modified our Configuration() method on the Startup class to use the overloaded Use<T>() method, which allows
us to specify the type which represents our middleware as a generic type argument.
Once again, we can run our application as-is, and all should work as expected.

Add Custom Extensions for IAppBuilder


Middleware implementations often utilize extension methods to extend the IAppBuilder interface, making it easier for the
developer to add middleware into the pipeline.
For example, we can add a static class for our extension methods like so:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

12 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Add Extension Methods to IAppBuilder for Our Custom Middleware:


public static class AppBuilderExtensions
{
public static void UseMyMiddleware(this IAppBuilder app)
{
app.Use<MyMiddlewareComponent>();
}
public static void UseMyOtherMiddleware(this IAppBuilder app)
{
app.Use<MyOtherMiddlewareComponent>();
}
}
Then we can update our Configuration() method again, and we see that our new extension methods are available:

Update Configuration() to Use Middleware Extension Methods:


public void Configuration(IAppBuilder app)
{
app.UseMyMiddleware();
app.UseMyOtherMiddleware();
}

Once again, running our application, and refreshing the browser, we see everything still works as expected.

Adding Middleware Configuration Options


Often we want the ability to pass in some configuration options for our middleware as it is added to the pipeline. For example,
suppose we wanted some control over the text to be displayed when MyMiddleware is invoked. Let's set things up so we can
pass in the message to be displayed during the call to Configuration(), instead of hard-coding it into the middleware
itself:

Add a String Configuration Parameter to MyMiddleware:


public class MyMiddlewareComponent
{
AppFunc _next;
// Add a member to hold the greeting:
string _greeting;
public MyMiddlewareComponent(AppFunc next, string greeting)
{
_next = next;
_greeting = greeting;
}
public async Task Invoke(IDictionary<string, object> environment)
{
IOwinContext context = new OwinContext(environment);
// Insert the _greeting into the display text:
await context.Response.WriteAsync(string.Format("<h1>{0}</h1>", _greeting));
await _next.Invoke(environment);
}
}
Of course, now the compiler is telling you you need to also modify the extension method we use to add
MyMiddlewareComponent to the pipeline, because we need to provide for the new constructor argument:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

13 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Modify the Extension Method to Accept and Pass the New Configuration Argument:
public static class AppBuilderExtensions
{
public static void UseMyMiddleware(this IAppBuilder app, string greetingOption)
{
app.Use<MyMiddlewareComponent>(greetingOption);
}
public static void UseMyOtherMiddleware(this IAppBuilder app)
{
app.Use<MyOtherMiddlewareComponent>();
}
}
And last, of course, we need to modify the code in Configuration() in the Startup class to pass in an acceptable
argument:

Modify the Configuration() Method to Pass an Appropriate Configuration Argument:


public void Configuration(IAppBuilder app)
{
app.UseMyMiddleware("This is the new greeting for MyMiddleware!");
app.UseMyOtherMiddleware();
}

In our simplistic example here, we were able add a string argument to our middleware constructor, and
everything worked out just fine. More commonly though, middleware will likely require more configuration
options. Also, this does not represent a very modular design approach. Instead, we might be better off using a
configuration class, to be passed to the constructor instead.

Use Configuration Objects for Configuring Middleware


To take our contrived example to the limit, let's rethink how we have implemented the configuration options for our
middleware. Instead of passing in an arbitrary string when we add the middleware to the pipeline, lets create a configuration
class which will use some pre-defined elements to construct a message.
First, let's create a (very contrived) configuration options class:

Configuration Options Class for MyMiddleware:


public class MyMiddlewareConfigOptions
{
string _greetingTextFormat = "{0} from {1}{2}";
public MyMiddlewareConfigOptions(string greeting, string greeter)
{
GreetingText = greeting;
Greeter = greeter;
Date = DateTime.Now;
}
public string GreetingText { get; set; }
public string Greeter { get; set; }
public DateTime Date { get; set; }
public bool IncludeDate { get; set; }
public string GetGreeting()
{
string DateText = "";
if(IncludeDate)
{

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

14 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

DateText = string.Format(" on {0}", Date.ToShortDateString());


}
return string.Format(_greetingTextFormat, GreetingText, Greeter, DateText);
}
}
Now, we will once again need to update our extension methods:

Modify Extension Methods to Pass Configuration Options:


public static class AppBuilderExtensions
{
public static void UseMyMiddleware(this IAppBuilder app,
MyMiddlewareConfigOptions configOptions)
{
app.Use<MyMiddlewareComponent>(configOptions);
}
public static void UseMyOtherMiddleware(this IAppBuilder app)
{
app.Use<MyOtherMiddlewareComponent>();
}
}

And finally, we now need to prepare our configuration during the Configuration() method of the
Startup class (which actually makes a lot of sense, no?):
Perform Middleware Configuration During Call to Configuration() Method:
public void Configuration(IAppBuilder app)
{
// Set up the configuration options:
var options = new MyMiddlewareConfigOptions("Greetings!", "John");
options.IncludeDate = true;
// Pass options along in call to extension method:
app.UseMyMiddleware(options);
app.UseMyOtherMiddleware();
}

Running the application, and refreshing the browser, we see the impact of our configuration options:
Refresh Browser to View Effect of Configuration Options:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

15 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Ok, we have just about exhausted the usefulness of these two example middleware components. Let's take a look at some (still
silly and contrived) mocked up components that represent something we might actually find in a pipeline.

Create Mock Components for Logging, and Authentication


As before, we are going to use some overly simple, contrived examples here. Katana actually provides for the addition of both
Logging and Authentication components, and we aren't going to get bogged down in the complexities of writing code to
actually perform either of these functions beyond mocking their effects on pipeline flow. Each of those topics could (and
probably will be) a post unto itself.
For now, let's add two new classes to our project. This time, though, let's add these as individual class files. This means we will
need to specify our AppFunc alias in each class, as well as make sure the using statements at the top of the file include

Microsoft.Owin.
Add a Mock Authentication Middleware Class as a Separate Code File:
using
using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
Owin;
Microsoft.Owin;

namespace KatanaConsole
{
// use an alias for the OWIN AppFunc:
using AppFunc = Func<IDictionary<string, object>, Task>;
public class SillyAuthenticationComponent
{
AppFunc _next;
public SillyAuthenticationComponent(AppFunc next)
{
_next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
IOwinContext context = new OwinContext(environment);
// In the real world we would do REAL auth processing here...
var isAuthorized = context.Request.QueryString.Value == "john";
if(!isAuthorized)
{
context.Response.StatusCode = 401;
context.Response.ReasonPhrase = "Not Authorized";
// Send back a really silly error page:
await context.Response.WriteAsync(string.Format("<h1>Error {0}-{1}",
context.Response.StatusCode,
context.Response.ReasonPhrase));
}
else
{
// _next is only invoked is authentication succeeds:
context.Response.StatusCode = 200;
context.Response.ReasonPhrase = "OK";
await _next.Invoke(environment);
}
}

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

16 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

}
}
In the above code, note that we totally fake an authorization request. Instead of grabbing an auth token from the request
header or some other secure way of doing things, we are cheating, and simply passing in a query string to check.
Also notice that if authorization fails, _next is never invoked. This matters in a moment.
Now let's add a hokey logging middleware:

Add a Mock Logging Middleware Class as a Separate Code File:


using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
Microsoft.Owin;

namespace KatanaConsole
{
// use an alias for the OWIN AppFunc:
using AppFunc = Func<IDictionary<string, object>, Task>;
public class SillyLoggingComponent
{
AppFunc _next;
public SillyLoggingComponent(AppFunc next)
{
_next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
// Pass everything up through the pipeline first:
await _next.Invoke(environment);
// Do the logging on the way out:
IOwinContext context = new OwinContext(environment);
Console.WriteLine("URI: {0} Status Code: {1}",
context.Request.Uri, context.Response.StatusCode);
}
}
}
Here, we are logging the incoming URI, and the status code of each request. Since we want to know the status code AFTER the
request has been processed, we are going to place this component first in the pipeline, but do no processing until after the call
to _next.Invoke() returns. In other words, we want to log status after all subsequent processing happens.
With this done, let's go ahead and add Extension methods for both of these components for ease of use with IAppBuilder:

Add Extension Methods for Auth and Logging Components:


public static class AppBuilderExtensions
{
public static void UseMyMiddleware(this IAppBuilder app,
MyMiddlewareConfigOptions configOptions)
{
app.Use<MyMiddlewareComponent>(configOptions);
}
public static void UseMyOtherMiddleware(this IAppBuilder app)
{
app.Use<MyOtherMiddlewareComponent>();
}

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

17 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

public static void UseSillyAuthentication(this IAppBuilder app)


{
app.Use<SillyAuthenticationComponent>();
}
public static void UseSillyLogging(this IAppBuilder app)
{
app.Use<SillyLoggingComponent>();
}
}
Now let's see how we might use these examples in modeling some "real-world" application behavior.

Requests, Responses, and Short-Circuiting the Middleware Pipeline


Recall our diagram of the middleware pipeline. We have a basic idea of how the request/response flow is supposed to occur
under normal circumstances. Let's use our two new middlewares, and re-configure our application somewhat.
First, we want to log the URL for each incoming request, and the status code of the response for each. Since we can't know the
final status code until all of the pipeline processing has completed, we will put this middleware in the pipeline first. in other
words, the logging middleware will be the first component to see each incoming request, and the last component to see the
outgoing repose.
Next, we will add our Authentication component. We want to test authentication early in the pipeline, and prevent unauthorized
users from proceeding any further than necessary into our application.
Finally, we will add our MyMiddleware component, which display a helpful greeting in the browser window.
We set all this up by modifying the Configuration() method of the Startup class as follows:

Configure Application with Mock Logging and Authentication Middleware:


public void Configuration(IAppBuilder app)
{
app.UseSillyLogging();
app.UseSillyAuthentication();
// Set up the configuration options:
var options = new MyMiddlewareConfigOptions("Greetings!", "John");
options.IncludeDate = true;
app.UseMyMiddleware(options);
}

Recall that the way we set up our Authentication middleware, the only valid login will be a URL with a query
string value of "john":
The "Authenticated User" Login URL:
http://localhost:8080/?john
So now, we can run our re-configured application and check out the refreshed view in the browser:

Browser View with "Authenticated" Request:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

18 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

Looks like everything worked as expected. Now lets take a look at our console window, and see how our logging middleware
did:

Console Output from Logging Middleware:

Well THAT'S interesting even though everything seems to have worked, we are getting a 404 ("Not Found") status code.
This is because the last middleware in our pipeline is calling _next.Invoke() , but there is no AppFunc available to call. In
a real middleware, this would likely need some proper handling.
In our case, the MyMiddleWareComponent actually appears to be designed to be a final component in a chain (the one
writing to the response body and returning to the client), so we could actually place the work of the component after the call to
invoke _next, knowing that unless some really special circumstances arose, there will not likely be any additional components.

Modify MyMiddleWareComponent to process after call to next:


public class MyMiddlewareComponent
{
AppFunc _next;
// Add a member to hold the greeting:
//string _greeting;
MyMiddlewareConfigOptions _configOptions;
public MyMiddlewareComponent(AppFunc next, MyMiddlewareConfigOptions configOptions)
{
_next = next;

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

19 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

_configOptions = configOptions;
}
public async Task Invoke(IDictionary<string, object> environment)
{
// If there is no next component, a 404 Not Found will be written as
// the response code here:
await _next.Invoke(environment);
IOwinContext context = new OwinContext(environment);
// Insert the _greeting into the display text:
await context.Response.WriteAsync(string.Format("<h1>{0}</h1>",
_configOptions.GetGreeting()));
// Update the response code to 200 OK:
context.Response.StatusCode = 200;
context.Response.ReasonPhrase = "OK";
}
}
If we run things again with our modified code, we should see the expected 200 OK response status in the console output.
Now, let's try reloading the browser with a different URI/query string:

An "Invalid" User URL:


http://localhost:8080/?bill

If we type this new, "invalid" user URL into the address bar of the browser, we see our poor-man's Error page:
Load Browser with "Invalid" User URL:

We can also see that our logging middleware properly logged the invalid attempt out to the console:

Console Output after "Invalid" login:

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

20 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

So what happened here in terms of our pipeline?


As you may have reasoned, the SillyAuthenticationComponent intentionally short-circuited the pipeline, by not
invoking the next component in the chain once use authentication failed. In this case, our pipeline flow looked something like
this instead of the previous diagram:

Flow in the Short-Circuited Pipeline Due to Failed Authentication:

Create MiddleWare Components as Stand-Alone Assemblies


Unlike most of what we have done here, most of the time, OWIN middleware would tend to be composed as a stand-alone
assembly in its own class library. Most likely, the middleware itself will take some dependencies on other libraries, but it would
not tend to be part of the application assembly itself.
To carry our most recent examples to their logical conclusion, we might extract each of our middleware components into its own
project, which, when ready for deployment, we might even host on Nuget as packages to be added to client projects.
Looking at our SillyAuthentication middleware as an example, let's add a new project to our solution, named
"SillyAuthentication." The project type should be "Class Library."
Once we have done that, we can use Manage Nuget Packages for Solution to add the Microsoft.Owin package to our new
class library.
Now, we want to add two classes to the project. First, add the SillyAuthentication class itself:

Add the SillyAuthentication Class to the New Project:


using System;
using System.Collections.Generic;

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

21 of 25

using
using
using
using
using

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

System.Linq;
System.Text;
System.Threading.Tasks;
Owin;
Microsoft.Owin;

namespace SillyAuthentication
{
// use an alias for the OWIN AppFunc:
using AppFunc = Func<IDictionary<string, object>, Task>;
public class SillyAuthentication
{
AppFunc _next;
public SillyAuthentication(AppFunc next)
{
_next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
IOwinContext context = new OwinContext(environment);
// In the real world we would do REAL auth processing here...
var isAuthorized = context.Request.QueryString.Value == "john";
if (!isAuthorized)
{
context.Response.StatusCode = 401;
context.Response.ReasonPhrase = "Not Authorized";
// Send back a really silly error page:
await context.Response.WriteAsync(string.Format("<h1>Error {0}-{1}",
context.Response.StatusCode,
context.Response.ReasonPhrase));
}
else
{
// _next is only invoked is authentication succeeds:
context.Response.StatusCode = 200;
context.Response.ReasonPhrase = "OK";
await _next.Invoke(environment);
}
}
}
}
Note in the above, that we have changed the name of the class from SillyAuthenticationComponent to simply
SillyAuthentication. Secondly, if we copies the code from the original project, we need to change the namespace from

KatanaConsole to SillyAuthentication.
Also, the way we set the alias for AppFunc must be specified for each code file where the alias will be used, so we need to do
that here as well.
Next, we will need to add a new AppBuilderExtensions class, so that when we reference our component within another
project, the extension method is there and ready to use:

Add a new AppBuilderExtensions Class to the new Project:


// Add reference to Owin:
using Owin;
namespace SillyAuthentication
{
public static class AppBuilderExtensions
{
public static void UseSillyAuthentication(this IAppBuilder app)

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

22 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

{
app.Use<SillyAuthentication>();
}
}
}
Obviously, since this assembly is specific to our SillyAuthentication component, we don't need the other extension
methods we defined in our original project.
We can do the same thing for our other components and we should have separate assemblies for the authentication
component, the logging component, and our MyMidddleware component. In each case, we will probably want to rename
the classes, dropping the "component" from each class name. Also, we need to use Manage Nuget Packages for Solution and
bring Microsoft.Owin into each project.
Make sure to specify the AppFunc alias in each file.
Finally, for the MyMiddleware project, we will make sure to bring the MyMiddlewareConfiguration into the project
as well.

Consuming the Stand-Alone Components from the Sample Project


Now, we can remove the SillyAuthenticationComponent class from our example project, as well as delete the
extension method we created related to the SillyAuthenticationComponent class.
If we go to Solution Explorer => Project Dependencies and indicate that KatanaConsole depends all three of our new class
library assemblies, and then also add a reference to each assembly using References => Add Reference, we are ready to clean up
and simplify our Project.cs file.
At this point, we can ditch all of the previous middleware class files we were using within the KatanaConsole project itself.
All we need is our main method, and our Startup class, like so:

Simplified KatanaSamples Project:


using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Text;
System.Threading.Tasks;
System.IO;

// Add the Owin Usings:


using Owin;
using Microsoft.Owin.Hosting;
using Microsoft.Owin;
// Add references to separate assemblies:
using SillyAuthentication;
using SillyLogging;
using MyMiddleware;
namespace KatanaConsole
{
class Program
{
static void Main(string[] args)
{
WebApp.Start<Startup>("http://localhost:8080");
Console.WriteLine("Server Started; Press enter to Quit");
Console.ReadLine();
}
}
public class Startup
{

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

23 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

public void Configuration(IAppBuilder app)


{
app.UseSillyLogging();
app.UseSillyAuthentication();
// Set up the configuration options:
var options = new MyMiddlewareConfigOptions("Greetings!", "John");
options.IncludeDate = true;
app.UseMyMiddleware(options);
}
}
}
If we have done everything correctly, and didn't miss a namespace change or anything like that, our KatanaConsole
application should run exactly as before. However, this time, we have pulled in our custom middleware as references, which
could just as easily come from Nuget.
In fact, the code in our Startup class may look fairly familiar to you. If you take a look at the Startup.auth.cs file from the Web Api
project template, you will see similar goings on, as ASP.NET Identity components are added to the OWIN pipeline.

Why Do I Care?
In this post we have taken a look at how the OWIN/Katana pipeline works, seen some of the basics of how middleware is
created and added to the pipeline, and developed an understanding of how our application interacts with the server in an
OWIN-based environment.
Why do you care?
For one thing, more and more of the .NET web development ecosystem is moving in this direction. At present, ASP.NET Web Api
can be hosted directly in the OWIN/Katana pipeline (although in the template projects available in Visual Studio, the Web Api is
added to the ASP.NET/System.Web pipeline instead), and the ASP.NET Identity Framework IS added to the Katana pipeline.
My understanding is, going forward ASP.NET 5 ("vNext") is going to go all the way in this direction, with the various bits and
pieces we want to add to our project added as pipeline components.
UPDATE 1/5/2015: ASP.NET 5 is indeed moving further in this direction. Katana itself will apparently be fully integrated into
ASP.NET 5. OWIN will be available through an interop, but greenfield projects will be best off using the integrated middleware
pipeline. However, most of what we discuss here will still apply, either directly, or conceptually (thanks to Rick Anderson and the
ASP.NET team for the clarification!).
Understanding the hosting and server environment, and being able to dig down into the abstractions will allow us to better
leverage the tools at our disposal, and write better, learner, meaner applications.
Are we going to be writing a bunch of custom middleware components ourselves? Likely not. But understanding how the pieces
fit is important.

Additional Resources and Items of Interest


Source Code on Github
The Owin Project Home Page
The Owin Specification
The Katana Project on Codeplex
ASP.NET Web Api 2.2: Create a Self-Hosted OWIN-Based Web Api from Scratch
ASP.NET Web Api: Understanding OWIN/Katana Authentication/Authorization Part II: Models and Persistence
ASP.NET Identity 2.0: Introduction to Working with Identity 2.0 and Web API 2.2
ASP.NET Identity 2.0: Customizing Users and Roles
ASP.NET Web Api: Unwrapping HTTP Error Results and Model State Dictionaries Client-Side

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

24 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share
About the Author
John Atten
Software Developer XIV Solutions
United States

My name is John Atten, and my username on many of my online accounts is xivSolutions. I am Fascinated by all things
technology and software development. I work mostly with C#, Javascript/Node.js, Various flavors of databases, and anything
else I find interesting. I am always looking for new information, and value your feedback (especially where I got something
wrong!)

You may also be interested in...


Understanding OWIN and
Katana

PaaS Built for Development: IBM


Bluemix Solves a Range of
Infrastructure and Middleware
Challenges

My understanding of OWIN &


Katana

Is SQL Server killing your


applications performance?

ASP.NET Web Api:


Understanding OWIN/Katana
Authentication/Authorization
Part I: Concepts

Ted Neward Coder Interview Developer Responsibility

Comments and Discussions


16 messages have been posted for this article Visit http://www.codeproject.com/Articles/864725/ASP-NETUnderstanding-OWIN-Katana-and-the-Middlewa to post and view comments on this article, or click here to get a print view

27/10/2015 21:43

ASP.NET: Understanding OWIN, Katana, and the Middleware Pipeline...

25 of 25

http://www.codeproject.com/Articles/864725/ASP-NET-Understandin...

with messages.

Permalink | Advertise | Privacy | Terms of Use | Mobile


Web03 | 2.8.151024.1 | Last Updated 26 Jan 2015

Selecione o idioma

Article Copyright 2015 by John Atten


Everything else Copyright CodeProject, 1999-2015

27/10/2015 21:43

You might also like