Introduction
If you are new to Owin and Katana and haven’t read the part1 of this series, I strongly recommend you to go back and read that part as well in order to have a better understanding of where we started from and where we are heading to.
- Understanding ASP.NET -Part1- Owin and Katana.
But if you already have a good understanding of Owin and project Katana, then you are ready to go from here.
In this part, we will build a simple Owin pipeline from scratch. We will take a look on how we can host our Owin pipeline into ASP.NET application and how we can plug-in different middlewares into the pipeline.
Building Owin Pipeline Step by Step
We’ll build a simple Katana based Owin pipeline with two middlewares in it, that can handle incoming HTTP requests and return response to the requesting client.
As we have discussed in part1, Owin comes with a pipeline of things called middlewares and a middleware is self-contained block code that can handle request, perform processing and can return response as well independent of host and other parts of the application. Now, let’s create the pipeline from an empty ASP.NET MVC project.
Step 1 Creating an empty ASP.NET project
We’ll create the pipeline from scratch so that we can have better understanding of what is required, what NuGet packages we need to install, and how much code it takes to build a simple Owin pipeline with project Katana.
Create a new ASP.Net project with empty template selected, and make sure to not to select any folder structure. Let’s just be simple for now.
When you select an empty template, you do actually get an empty project with some necessary assembly references and a web.config file.
At this point, web.config file only contains information about the runtime, target framework, and compiler configuration for both C# and VB which we will not be touching any way.
Step 2 Getting necessary NuGet Packages
Now, we’ll install some NuGet packages that we need to host Owin app in ASP.Net application.
Basically, we require three packages to host and run an Owin app inside ASP.NET.
- Owin
- Microsoft.Owin (Depends on Owin)
- Microsoft.Owin.Host.SystemWeb (Depends on Microsoft.Owin)
We will only install the host package which is Microsoft.Owin.Host.SystemWeb, and the NuGet Package Manager will resolve the dependencies for us and will install the other packages as well.
Open Package Manager Console window and type the following command.
NuGet will install the packages, will reference the DLLs and will add packages.config file in solution with some information about the packages we installed.
The actual Owin implementation of project Katana is inside the Microsoft.Owin package.
Step 3 Creating an Entry Point
Entry point is a point from where application starts and executes rest of the code. When we are working with Katana, we should have a class named Startup.cs in root directory of project.
Inside the class, we will create an actual entry point by creating a public method named Configuration with the following syntax and this is the default convention.
- public class Startup
- {
-
-
- public void Configuration(IAppBuilder app)
- {
-
- }
- }
You can name the method whatever you want and put it wherever you want, but if you do so, then you will have to add some configuration in web.config file to tell the runtime where the entry point is located.
- <appSettings>
- <add key="owin:AppStartup" value="OwinPipeline.Startup"/>
- </appSettings>
You can also specify the entry with an assembly level attribute.
- [assembly: OwinStartup(typeof(OwinPipeline.Startup))]
Step 4 Creating our first Middleware
Now, we have an entry point. Let’s create a simple middleware that will return a peaceful message to client. To plug in a middleware into Owin pipeline, we’ll use the “use” method of IAppBuilder object that takes a delegate as parameter.
- public void Configuration(IAppBuilder app)
- {
- app.Use(async (context, nextMiddleWare) => {
-
- });
- }
The first argument in lambda expression is of type IOwinContext and the second one is another delegate.
Syntax may be confusing because we were expecting a middleware that will take a dictionary object as an argument and will return a task object.
As we have discussed earlier in the first part, Katana is not by the book implementation of Owin specification; instead people at Microsoft implemented it in their own way for ease of use to average developer. Now, let me explain the confusion here.
- IOwinContext: is actually a wrapper around environment dictionary that have defined some common task to perform on dictionary object.
- Func<Task>: is a delegate that actually returns a task when it’s called.
This is how Microsoft implemented Owin. Now, we have our middleware ready but the one thing left is returning a peaceful message to client. This is how we’ll do that.
- app.Use(async (context, nextMiddleWare) => {
- await context.Response.WriteAsync("Peace be on world.");
- });
WriteAsync method on Response property of context object is actually writing message to response stream stored in environment dictionary object under the key “Owin.ResponseBody”.
Now, start the app without debugger attached, and you will see your message coming back from Server.
Congratulations, our first middleware is up and running.
Step 5 Building a pipeline
A pipeline with one middleware is not much of a pipeline. Now, let’s create another middleware that will log information about incoming request path and response status code. Having two middlewares in pipeline will give us a nice opportunity to experience request and response flow in pipeline.
- app.Use(async (context, nextMiddleWare) =>
- {
- Trace.WriteLine("Request: " + context.Request.Path);
-
- await nextMiddleWare();
-
-
-
- Trace.WriteLine("Responce Status Code:" + context.Response.StatusCode);
- });
Now, run the app with debugger attached and open the output window to see logged messages.
We have a fully working OWIN pipeline with two middlewares and the goal of our part 2 is completed.
Thank you for coming this far with me. Stay tuned for the next part. In next part, we’ll go further in creating middlewares and plugging middlewares in pipeline with extension methods on IAppBuilder.
Startup.cs
- using System;
- using System.Threading.Tasks;
- using Microsoft.Owin;
- using Owin;
- using System.Diagnostics;
-
- [assembly: OwinStartup(typeof(OwinPipeline.Startup))]
-
- namespace OwinPipeline
- {
- public class Startup
- {
-
-
- public void Configuration(IAppBuilder app)
- {
- app.Use(async (context, nextMiddleWare) =>
- {
- Debug.WriteLine("Request: " + context.Request.Path);
-
- await nextMiddleWare();
-
-
-
- Debug.WriteLine("Responce Status Code:" + context.Response.StatusCode);
- });
-
- app.Use(async (context, nextMiddleWare) =>
- {
- await context.Response.WriteAsync("Peace be on world.");
- });
- }
- }
- }