In the previous article What is OWIN? A Beginners Guide, we have learned the basics of OWIN specification and the benefits it is adding to Microsoft’s web frameworks. In this article, let’s build a simple Owin based application to have a better understanding.
As I said in previous article, implementing AppFunc delegate alone will not make our application Owin complaint, it also need some additional components that runs above or as an add-on to our host and web framework (Asp.Net) to provide this capability. These are the components that are delivered as part of Project Katana as Nuget packages.
Please note the newer version of Asp.Net called Asp.Net Core uses OWIN by default. So, if you are creating a new Asp.Net Core application, Visual Studio will include all the required Nuget packages automatically as part of the project template. This article is just for learning purpose by including Katana Nuget packages ourselves. It will be useful when you want to add Owin capability to your existing asp.net application.
Using Katana Nuget packages, we can create and run our Owin-based application in 3 different ways.
-
Self-Host (in our own program/windows services)
-
OwinHost.exe(command-line tool)
-
Microsoft.Owin.Host.SystemWeb (Owin server for traditional Asp.Net pipeline in IIS)
Let’s create a new Console application to create our new Owin based application. You can use Visual Studio 2012 or 2013 or 2015.
Using Self-Host
After creating your console application, let’s add the necessary Nuget packages into our project.
Follow the below steps to do this,
-
Right-click your project in solution explorer and click “Manage Nuget Packages..”
Enter the package name "Microsoft.Owin.Hosting" in search textbox and click Enter. On Search results screen, click “Install” button against the Nuget package. Click “I Accept” button. This will download and install the package into your project with all the dependency packages.
Alternatively, you can use the “Package Manager Console” to install the Nuget package. To do this, Click Tools Menu> Nuget Package Manager > Package Manager Console. Type the below command and enter.
PM> Install-Package Microsoft.Owin.Hosting
-
Repeat the above steps to install another required package called "Microsoft.Owin.Host.HttpListener".
Now, we have all the necessary package to build an Owin-capable application with self-host.
Let’s build a simple application that can render a simple message "My First Owin Application". As I said in previous article, the entry point to our application is AppFunc delegate implementation (or a Startup class) which the host will call to initiate the app. To do this, add a class file “Startup.cs” into your project. Code below,
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Run(context =>
{
context.Response.ContentType = "text/plain";
return context.Response.WriteAsync("My First Owin Application");
});
}
}
Include namespace Microsoft.Owin and Owin in the class file.
When a request is made, the method Configuration(IAppBuilder app) will be called by the host by injecting a concrete IAppBuilder object and this method will inject the plain text “My First Owin Application” into the response stream and it will return.
Note-
If you note this method signature, it does not resemble in any way to the signature of AppFunc delegate in Owin specification. For now, let’s ignore this and we will see why it is like that in the coming sections.
Now, let’s host this simple app into a self-hosting process. On the void Main() method, lets add code to do self-hosting and listen on port 5001. Code below.
public static void Main(string[] args)
{
WebApp.Start("http://localhost:5001");
Console.WriteLine("Server Started...Press any key to exit");
Console.ReadLine();
}
Include the namespace “Microsoft.Owin.Hosting” for the above code to work.
That’s it, you are done! Click F5 to run your application. Visit http://localhost:5001/ from browser and you can see the output like below.
Using OwinHost.exe
We will use the same code and will try to run it from OwinHost.exe host.
To do this, go to Nuget package manager and type OwinHost.exe in the search textbox, install the package. Once installed, go to command prompt and navigate to project root directory and run the OwinHost.exe by specifying its relative path. As you can see, the packages are downloaded to a folder called “Packages” that resides in parent directory where the solution file is placed.
D:\xxx\ProjectRool>..\packages\OwinHost.3.0.1\tools\OwinHost.exe
Please see the image below,
Note - This exe requires the project dll placed directly inside bin directory and not inside Debug or Release folder. It will throw EntryPointNotFoundException error if not found.
Visit http://localhost:5000 and you can see the output.
With Asp.Net Core release, we have a cross platform webserver known as Kestrel, it is the default webserver included in Visual Studio for Asp.Net Core projects.
Using Microsoft.Owin.Host.SystemWeb - IIS Asp.Net Pipeline
Using this option, we can host our Owin application in IIS webserver. So, let’s create a new Asp.Net web application project using Visual Studio.
Now, from Nuget package manager let’s add the Nuget package Microsoft.Owin.Host.SystemWeb which provides the Owin server add-on to run our application in traditional Asp.Net pipeline under IIS. Add the Startup class which we used above.
Hit F5, and you will see the output text rendered by Owin Startup class in the browser.
Note: It is also possible to run your application created for Self-Host and OwinHost.exe under IIS instead of creating a new web project. First you need to convert the console application into a class library project. To do this, right click your console project from Solution explorer and click Properties. Under Application tab, change the Output type to “Class Library”. This will compile your code into .dll instead of exe. Now add the Microsoft.Owin.Host.SystemWeb Nuget package into your project. Make sure the application dll and Microsoft.Owin.Host.SystemWeb.dll are copied directly into your bin instead of Debug folder. To host it in IIS, open inetmgr and create a new website and specify your project root as website root directory. Visit the site from Browser and you will see the output.
With this, we have learned to create a simple owin-based application and 3 ways to host it.
Now, let’s understand why the Startup class method does not match the AppFunc delegate signature and how the host finds this method and invokes it.
Owin Startup Method Signature and Invocation
As per OWIN specification, the dependency between application and webserver is removed by adding an abstraction layer using AppFunc delegate Func<IDictionary<string, object>, Task>. But the Startup method we used above did not match the signature of AppFunc or the specification did not mention any method similar to the Startup.Configuration(IAppBuilder) method signature. It is because we are using Owin implementation provided by Project Katana and not implementing the specification by our own. Project Katana implements the Owin specification and it expects the application to provide a Startup class implementation in the format we created above. IAppBuilder interface can also viewed as a wrapper with some additional utility methods for adding middleware components into the Owin pipeline.
To invoke the app, the katana host will look in the following places for identifying the startup class method.
-
The startup class type is identified if it is passed as type argument in self-host method.
WebApp.Start<Startup1>()
Or by passing the startup class type name as command-line argument for OwinHost.exe
D:\app>..\packages\OwinHost.3.0.1\tools\OwinHost.exe FirstOwinApp.Startup1
-
It will look for AppSetting key owin:AppStartup with type name as value.
-
It will look for a type with OwinStartup attribute in the project assembly,
[assembly: OwinStartup(typeof(FirstOwinApp.Startup1))]
-
Finally, using reflection it will look for a type with name “Startup” and with a method signature(as below) in all the project assembly.
public void Configuration(IAppBuilder app)
The application will be invoked if the Startup method is found in any of the above places, if not it will throw the below error.
Error: System.EntryPointNotFoundException
The following errors occurred while attempting to load the app.
- No assembly found containing an OwinStartupAttribute.
- No assembly found containing a Startup or [AssemblyName].Startup class.