OWIN Startup Class Detection
This tutorial shows how to configure which OWIN startup class is loaded. For more information on OWIN, see An Overview of Project Katana. This tutorial was written by Rick Anderson ( @RickAndMSFT ), Praburaj Thiagarajan, and Howard Dierking ( @howard_dierking ).
Prerequisites
OWIN Startup Class Detection
Every OWIN Application has a startup class where you specify components for the application pipeline. There are different ways you can connect your startup class with the runtime, depending on the hosting model you choose (OwinHost, IIS, and IIS-Express). The startup class shown in this tutorial can be used in every hosting application. You connect the startup class with the hosting runtime using one of the these approaches:
Naming Convention: Katana looks for a class named
Startup
in namespace matching the assembly name or the global namespace.OwinStartup Attribute: This is the approach most developers will take to specify the startup class. The following attribute will set the startup class to the
TestStartup
class in theStartupDemo
namespace.[assembly: OwinStartup(typeof(StartupDemo.TestStartup))]
The
OwinStartup
attribute overrides the naming convention. You can also specify a friendly name with this attribute, however, using a friendly name requires you to also use theappSetting
element in the configuration file.The appSetting element in the Configuration file: The
appSetting
element overrides theOwinStartup
attribute and naming convention. You can have multiple startup classes (each using anOwinStartup
attribute) and configure which startup class will be loaded in a configuration file using markup similar to the following:<appSettings> <add key="owin:appStartup" value="StartupDemo.ProductionStartup" /> </appSettings>
The following key, which explicitly specifies the startup class and assembly can also be used:
<add key="owin:appStartup" value="StartupDemo.ProductionStartup, StartupDemo" />
The following XML in the configuration file specifies a friendly startup class name of
ProductionConfiguration
.<appSettings> <add key="owin:appStartup" value="ProductionConfiguration" /> </appSettings>
The above markup must be used with the following
OwinStartup
attribute which specifies a friendly name and causes theProductionStartup2
class to run.[assembly: OwinStartup("ProductionConfiguration", typeof(StartupDemo.ProductionStartup2))] namespace StartupDemo { public class ProductionStartup { public void Configuration(IAppBuilder app) { app.Run(context => { string t = DateTime.Now.Millisecond.ToString(); return context.Response.WriteAsync(t + " Production OWIN App"); }); } } public class ProductionStartup2 { public void Configuration(IAppBuilder app) { app.Run(context => { string t = DateTime.Now.Millisecond.ToString(); return context.Response.WriteAsync(t + " 2nd Production OWIN App"); }); } } }
To disable OWIN startup discovery add the
appSetting owin:AutomaticAppStartup
with a value of"false"
in the web.config file.<add key="owin:AutomaticAppStartup" value="false" />
Create an ASP.NET Web App using OWIN Startup
Create an empty Asp.Net web application and name it StartupDemo. - Install
Microsoft.Owin.Host.SystemWeb
using the NuGet package manager. From the Tools menu, select NuGet Package Manager, and then Package Manager Console. Enter the following command:Install-Package Microsoft.Owin.Host.SystemWeb
Add an OWIN startup class. In Visual Studio 2017 right-click the project and select Add Class.- In the Add New Item dialog box, enter OWIN in the search field, and change the name to Startup.cs, and then select Add.
The next time you want to add an Owin Startup class, it will be in available from the Add menu.
Alternatively, you can right-click the project and select Add, then select New Item, and then select the Owin Startup class.
Replace the generated code in the Startup.cs file with the following:
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; using System.IO; //[assembly: OwinStartup(typeof(StartupDemo.Startup))] namespace StartupDemo { public class Startup { public void Configuration(IAppBuilder app) { app.Use((context, next) => { TextWriter output = context.Get<TextWriter>("host.TraceOutput"); return next().ContinueWith(result => { output.WriteLine("Scheme {0} : Method {1} : Path {2} : MS {3}", context.Request.Scheme, context.Request.Method, context.Request.Path, getTime()); }); }); app.Run(async context => { await context.Response.WriteAsync(getTime() + " My First OWIN App"); }); } string getTime() { return DateTime.Now.Millisecond.ToString(); } } }
The
app.Use
lambda expression is used to register the specified middleware component to the OWIN pipeline. In this case we are setting up logging of incoming requests before responding to the incoming request. Thenext
parameter is the delegate ( Func < Task > ) to the next component in the pipeline. Theapp.Run
lambda expression hooks up the pipeline to incoming requests and provides the response mechanism.Note
In the code above we have commented out the
OwinStartup
attribute and we're relying on the convention of running the class namedStartup
.- Press F5 to run the application. Hit refresh a few times.Note: The number shown in the images in this tutorial will not match the number you see. The millisecond string is used to show a new response when you refresh the page. You can see the trace information in the Output window.
Add More Startup Classes
In this section we'll add another Startup class. You can add multiple OWIN startup class to your application. For example, you might want to create startup classes for development, testing and production.
Create a new OWIN Startup class and name it
ProductionStartup
.Replace the generated code with the following:
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(StartupDemo.ProductionStartup))] namespace StartupDemo { public class ProductionStartup { public void Configuration(IAppBuilder app) { app.Run(context => { string t = DateTime.Now.Millisecond.ToString(); return context.Response.WriteAsync(t + " Production OWIN App"); }); } } }
Press Control F5 to run the app. The
OwinStartup
attribute specifies the production startup class is run.Create another OWIN Startup class and name it
TestStartup
.Replace the generated code with the following:
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; [assembly: OwinStartup("TestingConfiguration", typeof(StartupDemo.TestStartup))] namespace StartupDemo { public class TestStartup { public void Configuration(IAppBuilder app) { app.Run(context => { string t = DateTime.Now.Millisecond.ToString(); return context.Response.WriteAsync(t + " Test OWIN App"); }); } } }
The
OwinStartup
attribute overload above specifiesTestingConfiguration
as the friendly name of the Startup class.Open the web.config file and add the OWIN App startup key which specifies the friendly name of the Startup class:
<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="owin:appStartup" value="TestingConfiguration" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> </system.web> </configuration>
Press Control F5 to run the app. The app settings element takes precedent, and the test configuration is run.
Remove the friendly name from the
OwinStartup
attribute in theTestStartup
class.[assembly: OwinStartup(typeof(StartupDemo.TestStartup))]
Replace the OWIN App startup key in the web.config file with the following:
<add key="owin:appStartup" value="StartupDemo.TestStartup" />
Revert the
OwinStartup
attribute in each class to the default attribute code generated by Visual Studio:[assembly: OwinStartup(typeof(StartupDemo.Startup))] [assembly: OwinStartup(typeof(StartupDemo.ProductionStartup))] [assembly: OwinStartup(typeof(StartupDemo.TestStartup))]
Each of the OWIN App startup keys below will cause the production class to run.
<add key="owin:appStartup" value="StartupDemo.ProductionStartup" /> <add key="owin:appStartup" value="StartupDemo.ProductionStartup, StartupDemo" /> <add key="owin:appStartup" value="StartupDemo.ProductionStartup.Configuration, StartupDemo" />
The last startup key specifies the startup configuration method. The following OWIN App startup key allows you to change the name of the configuration class to
MyConfiguration
.<add key="owin:appStartup" value="StartupDemo.ProductionStartup2.MyConfiguration" />
Using Owinhost.exe
Replace the Web.config file with the following markup:
<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="owin:appStartup" value="StartupDemo.Startup" /> <add key="owin:appStartup" value="StartupDemo.TestStartup" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> </system.web> </configuration>
The last key wins, so in this case
TestStartup
is specified.Install Owinhost from the PMC:
Install-Package OwinHost
Navigate to the application folder (the folder containing the Web.config file) and in a command prompt and type:
..\packages\Owinhost<Version>\tools\Owinhost.exe
The command window will show:
C:\StartupDemo\StartupDemo>..\packages\OwinHost.2.0.0\tools\Owin Host.exe Starting with the default port: 5000 (http://localhost:5000/) Started successfully Press Enter to exit
Launch a browser with the URL
http://localhost:5000/
.OwinHost honored the startup conventions listed above.
In the command window, press Enter to exit OwinHost.
In the
ProductionStartup
class, add the following OwinStartup attribute which specifies a friendly name of ProductionConfiguration.[assembly: OwinStartup("ProductionConfiguration", typeof(StartupDemo.ProductionStartup))]
In the command prompt and type:
..\packages\OwinHost.2.0.0\tools\OwinHost.exe ProductionConfiguration
The Production startup class is loaded.
Our application has multiple startup classes, and in this example we have deferred which startup class to load until runtime.
Test the following runtime startup options:
..\packages\OwinHost.2.0.0-rc1\tools\OwinHost.exe StartupDemo.TestStartup ..\packages\OwinHost.2.0.0-rc1\tools\OwinHost.exe "StartupDemo.TestStartup,StartupDemo" ..\packages\OwinHost.2.0.0-rc1\tools\OwinHost.exe StartupDemo.TestStartup.Configuration ..\packages\OwinHost.2.0.0-rc1\tools\OwinHost.exe "StartupDemo.TestStartup.Configuration,StartupDemo"