Understanding ASP.Net -Part 2- Building an Owin Pipeline


Introduction

In this part, we will build a simple Owin pipeline from scratch. We will take a look at how we can host our Owin pipeline into ASP.Net application and how we can plug in different middlewares into the pipeline.
If you are new to Owin and Katana and haven’t read the part1 in this series I strongly recommend you to you go back and read that part as well, So you can have better understanding of from where we started and where we are heading.
  1.  Understanding ASP.Net -Part1- Owin and Katana.
But if you already have a good understanding of Owin and what project katana is then you are ready to go from here.

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 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 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 required three packages to host and run and Owin app inside ASP.Net.
  1. Owin
  2. Microsoft.Owin (Depends on Owin)
  3. Microsoft.Owin.Host.SystemWeb (Depends on Microsoft.Owin)
We will only install the host package which is Microsoft.Owin.Host.SystemWeb and NuGet Package Manager will resolve the dependencies for us and will install the other packages as well.
Open up Package Manager Console window and type 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 execute 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 following syntax and this is the default convention.

public class Startup
    {
              /*IAppBuilder object is used to plugin middlewares
        into pipeline*/
        public void Configuration(IAppBuilder app)
        {
          
        }
    }

You can name 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 that 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 how Microsoft implemented Owin. Now we have our middleware ready but one thing left is returning a peaceful message to client and this 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 our 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();//will forward request to next middleware

                /*at this point responce headers will be sent client
                /and response body is about to sent*/
                Trace.WriteLine("Responce Status Code:" + context.Response.StatusCode);
            });

Now run the app with debugger attached and open the output window to see logged messages.
  

Now we have a fully working OWIN pipeline with two middlewares and the goal of our part2 is completed.

Thank you for coming this far with me, stay tuned for 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
    {
        /*IAppBuilder object is used to plugin middlewares
        to build a pipeline*/
        public void Configuration(IAppBuilder app)
        {
            app.Use(async (context, nextMiddleWare) =>
            {
                Debug.WriteLine("Request: " + context.Request.Path);
               
  await nextMiddleWare();//will forward request to next middleware

                /*at this point responce headers will be sent client
                /and response body is about to sent*/
                Debug.WriteLine("Responce Status Code:" + context.Response.StatusCode);
            });

            app.Use(async (context, nextMiddleWare) =>
            {
                await context.Response.WriteAsync("Peace be on world.");
            });
        }
    }
}

Comments

Popular posts from this blog

Understanding ASP.Net -Part3- Building Reusable and Configurable Middlewares

Understanding ASP.Net - Part1- Owin and Katana Introduction