CHAPTER 4
In the previous chapter, you learned how to build OWIN-based applications using web frameworks and middleware components written by others, but you will probably need to write custom components specific to your application.
In this chapter, you will learn how to do it, both as simple inline functions and as more isolated components in their own class and library.
As you have seen in Chapter 1, an OWIN middleware component is basically just a function with the AppFunc signature.
using AppFunc = Func< IDictionary<string, object>, // Environment Task>; // Done |
To use a middleware component, you also have to register it in the OWIN pipeline via the IAppBuilder interface. Even if not strictly defined in the specs (this topic is actually being discussed in the OWIN list at the time of writing), you register a middleware component by calling the Use method of that interface and supplying a function with the following signature.
Func<AppFunc, AppFunc> |
Basically, you pass a function that takes the next component in the OWIN pipeline and returns a new middleware component to the Use method. Stated like this, it sounds complicated, so we better look at an example.
app.Use(new Func<Func<IDictionary<string, object>, Task> /*next*/ , Func<IDictionary<string, object> /*env*/, Task>> (next => (async env => { var response = env["owin.ResponseBody"] as Stream; string pre = "\tMW 2 - Before (Inline AppFunc)\r\n"; string post = "\tMW 2 - After (Inline AppFunc)\r\n"; await response.WriteAsync(Encoding.UTF8.GetBytes(pre), 0, pre.Length); await next.Invoke(env); await response.WriteAsync(Encoding.UTF8.GetBytes(post), 0, post.Length); }))); |
The one shown in the previous code listing is a very simple middleware that, using only what comes with the OWIN specs, writes two strings ("Before" and "After") to the response stream while calling the next component in the pipeline. The next variable is the parameter that gets passed in the "outer" function, while env is the input parameter of the "inner" function. Also notice that the function accesses the environment dictionary and casts the value to the right type before using them.
This inline method is okay if you just want to add some tracing, but in case your middleware class is more complicated, you might want to create a separate class.
public class RawOwinMiddleware { private Func<IDictionary<string, object>, Task> next;
public RawOwinMiddleware(Func<IDictionary<string, object>, Task> next) { this.next = next; }
public async Task Invoke(IDictionary<string, object> env) { var response = env["owin.ResponseBody"] as Stream; string pre = "\t\t\tMW 4 - Before (RawOwinMiddleware)\r\n"; string post = "\t\t\tMW 4 - After (RawOwinMiddleware)\r\n"; await response.WriteAsync(Encoding.UTF8.GetBytes(pre), 0, pre.Length); await next.Invoke(env); await response.WriteAsync(Encoding.UTF8.GetBytes(post), 0, post.Length); } } |
It does essentially the same things, but the IAppBuilder instance behaves differently when it receives a Type instead of an inline lambda expression. In this case, it creates an instance of the middleware type, passing to the constructor the next element in the pipeline, and then it calls the Invoke method when the middleware has to be executed.
To register this middleware component, you need to pass its type to the Use method: app.Use(typeof(RawOwinMiddleware)).
Using the OWIN specs directly is good if you want to better understand how middleware works and gets registered in the pipeline, or if you want to release it so that it works in all OWIN servers without taking a dependency on the Microsoft.Owin DLL. But if none of these constraints are a problem, you can build middleware using the Use extension method provided by the Katana project, which needs a Func<IOwinContext, Func<Task>, Task>—basically a function that receives the IOwinContext and the next element in the pipeline and returns the Task to execute.
app.Use(async (context, next) => { await context.Response.WriteAsync("MW 1 - Before (Katana inline middleware)\r\n"); await next(); await context.Response.WriteAsync("MW 1 - After (Katana inline middleware)\r\n"); }); |
This code example does the same thing as the one in the previous section, but is much more succinct.
Of course, with the Katana helpers you can write middleware as a separate class.
public class LoggerMiddleware : OwinMiddleware { public LoggerMiddleware(OwinMiddleware next) : base(next) {
}
public override async Task Invoke(IOwinContext context) { await context.Response.WriteAsync("\t\t\t\tMW 5 - Before (Katana helped middleware class)\r\n"); await this.Next.Invoke(context); await context.Response.WriteAsync("\t\t\t\tMW 5 - After (Katana helped middleware class)\r\n"); } } |
In this case, you have to write a class that inherits from OwinMiddleware, but the rest is almost the same as what you wrote using just the OWIN specs. Also you need to register the component by passing its type to the Use method: app.Use(typeof(LoggerMiddleware)).
As seen in Chapter 2, the big advantage of using the Microsoft.Owin helpers is the IOwinContext that wraps all the elements in the OWIN environment dictionary in a strongly typed fashion.
Before closing the chapter, I want to remind you of a pretty important point about middleware: all their "before" actions are executed in the order in which the components are registered in the pipeline, while the "after" actions are executed in the opposite order. This is also well-visualized in Figure 36.
public void Configuration(IAppBuilder app) { app.Use(async (context, next) => { await context.Response.WriteAsync("MW 1 - Before (Katana helped inline middleware)"+Environment.NewLine); await next(); await context.Response.WriteAsync("MW 1 - After (Katana helped inline middleware)" + Environment.NewLine); });
app.Use(new Func<Func<IDictionary<string, object>, Task> /*next*/ , Func<IDictionary<string, object> /*env*/, Task>> (next => (async env => { var response = env["owin.ResponseBody"] as Stream; string pre = "\tMW 2 - Before (Inline AppFunc)\r\n"; string post = "\tMW 2 - After (Inline AppFunc)\r\n"; await response.WriteAsync(Encoding.UTF8.GetBytes(pre), 0, pre.Length); await next.Invoke(env); await response.WriteAsync(Encoding.UTF8.GetBytes(post), 0, post.Length); })));
app.Use(new Func<Func<IDictionary<string, object>, Task> /*next*/ , Func<IDictionary<string, object> /*env*/, Task>>
app.Use(typeof(RawOwinMiddleware)); app.Use(typeof(LoggerMiddleware));
app.Run(ctx => { return ctx.Response.WriteAsync("\t\t\t\t\tApp - Hello World!" + Environment.NewLine); }); }
private async Task Invoke(Func<IDictionary<string, object>, Task> next , IDictionary<string, object> env) { var response = env["owin.ResponseBody"] as Stream; string pre = "\t\tMW 3 - Before (Delegate)\r\n"; string post = "\t\tMW 3 - After (Delegate)\r\n"; await response.WriteAsync(Encoding.UTF8.GetBytes(pre), 0, pre.Length); await next.Invoke(env); await response.WriteAsync(Encoding.UTF8.GetBytes(post), 0, post.Length); } } |
The following figure shows how all the components defined in this chapter are executed if all of them were registered in a pipeline as in the previous code listing.

In this chapter, you have learned how to build custom middleware components.
In the next chapter, you will learn how to secure your application, configure other middleware components to enable the standard form authentication, and also how to leverage social authentication with Twitter, Facebook, Google, and others.