本教程讲解如何配置哪个OWIN启动类被加载。

OWIN启动类检测

每个OWIN应用程序都有一个启动类,可以在这个类里为应用程序管道指定组件。有不同的方式可以将启动类与运行时关联起来,这依赖于选择的托管模型(OwinHost,IIS,IIS-Express)。本教程中的启动类可以用在每个托管的程序中。可以使用下面这些方法中的一种将启动类与运行时进行关联。

  1. 命名约定:Katana在匹配的程序集或全局命名空间中查找名为Startup的类。
  2. OwinStartup特性:大多数开发人员使用这种方法指定启动类。下面的特性设置StartupDemo命名空间中的TestStartup类为启动类。
    [assembly: OwinStartup(typeof(StartupDemo.TestStartup))]
    

    OwinStartup特性重写了命名约定。可以使用这个特性指定一个友好的名字,然而,使用友好的名字还需要使用配置文件的appSetting元素。

  3. 配置文件的appSetting:appSetting元素重写了OwinStartup特性和命名约定。可以有多个启动类(每个使用OwinStartup特性),在配置文件中使用类似于下面的标记配置哪个启动类被加载。
    <appSettings>
      <add key="owin:appStartup" value="StartupDemo.ProductionStartup" />
    </appSettings>
    

    也可以显示指定启动类和程序集:

    <add key="owin:appStartup" value="StartupDemo.ProductionStartup, StartupDemo" />
    

    下面的XML指定了一个名为ProductionConfiguration的友好的启动类名称:

    <appSettings>
      <add key="owin:appStartup" value="ProductionConfiguration" />
    </appSettings>
    

    上面的标记必须和下面的OwinStartup特性一起使用来引起ProductionStartup2类运行。

    [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");
                });
            }
        }
    }
    
  4. 设置appSetting的owin:AutomaticAppStartup值为false禁用OWIN启动发现:
    <add key="owin:AutomaticAppStartup " value="false" />
    

使用OWIN Startup创建 ASP.NET Web App

  1. 创建一个空的ASP.NET web程序,命名为StartupDemo
  2. 使用NuGet程序包管理器安装Microsoft.Owin.Host.SystemWeb。
    Install-Package Microsoft.Owin.Host.SystemWeb
    
  3. 添加一个OWIN启动类。Visual Studio 2013中,在项目上右击,选择添加类
  4. 弹出添加新项对话框,在搜索框中输入OWIN,更改名字为Startup.cs,然后点击添加
    OWIN启动类检测-程序旅途
    下次再添加OWIN Startup类的时候,就可以直接从添加菜单中添加了。OWIN启动类检测-程序旅途也可以右击项目,选择添加,然后选择新建项,然后选择Owin Startup类。
  5. 将Startup.cs文件替换成如下代码:
    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();
            }
        }
    }
    
    

    app.Use拉姆达表达式注册指定的中间件到OWIN管道。在这个例子中,我们在响应传入请求前建立传入请求的日志记录。next参数是管道中下一个组件的委托。app.Run拉姆达表达式将管道挂钩到传入请求并提供响应机制。注意:在上面的代码,注释掉了OwinStartup特性,我们依赖于运行名为Startup的类这一约定。

  6. 按F5运行程序。多刷新几次试试。
    OWIN启动类检测-程序旅途
    注意:上图中你看到的数字可能跟你的不一样。当你刷新页面时,使用毫秒字符串来显示一个新的响应。你可以在输出窗口看到跟踪信息。
    OWIN启动类检测-程序旅途

添加更多启动类

本节,将添加另外一个启动类。可以在一个程序中添加多个OWIN启动类。比如,你可能想创建用于开发的启动类、测试的启动类和生产的启动类。

  1. 创建一个OWIN Startup类,命名为ProductionStartup。
  2. 使用下面的代码替换。
    [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");
                });
            }
        }
    }
    
  3. 按Ctrl+F5运行程序。OwinStartup特性指定production startup类运行。
    OWIN启动类检测-程序旅途
  4. 创建另一个OWIN Startup类,命名为TestStartup。
  5. 使用下面的代码替换。
    [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");
                });
            }
        }
    }
    

    OwinStartup特性重载指定TestingConfiguration作为Startup类的友好名称。

  6. 打开web.config文件,添加OWIN App startup键指定Startup类的友好名称。
      <appSettings>
        <add key="owin:appStartup" value="TestingConfiguration" />
      </appSettings>
    
  7. 按Ctrl+F5运行程序。app settings元素优先,test configuration运行。OWIN启动类检测-程序旅途
  8. 从TestStartup类的OwinStartup特性上移除友好名称。
    [assembly: OwinStartup(typeof(StartupDemo.TestStartup))]
    
  9. 在web.config文件中修改OWIN App startup键入如下:
        <add key="owin:appStartup" value="StartupDemo.TestStartup" />
    
  10. 恢复每个类的OwinStartup到Visual Studio生成的默认特性。
    [assembly: OwinStartup(typeof(StartupDemo.Startup))]
    [assembly: OwinStartup(typeof(StartupDemo.ProductionStartup))]
    [assembly: OwinStartup(typeof(StartupDemo.TestStartup))]
    
  11. 下面的每一个OWIN App startup键都会引起production类运行。
        <add key="owin:appStartup" value="StartupDemo.ProductionStartup" />
        <add key="owin:appStartup" value="StartupDemo.ProductionStartup, StartupDemo" />
        <add key="owin:appStartup" value="StartupDemo.ProductionStartup.Configuration, StartupDemo" />
    
  12. 最后一个startup键指定startup的配置方法。下面的OWIN App startup键允许修改Configuration方法名为MyConfiguration。
        <add key="owin:appStartup" value="StartupDemo.ProductionStartup2.MyConfiguration" />
    

使用Owinhost.exe

  1. 使用下面的标记替换web.config文件的appSettings。
      <appSettings>
        <add key="owin:appStartup" value="StartupDemo.Startup" />
        <add key="owin:appStartup" value="StartupDemo.TestStartup" />
      </appSettings>
    

    最后一个键胜出,所以本例中TestStartup被指定。

  2. 从PMC中安装Owinhost
    Install-Package OwinHost
    
  3. 导航到程序文件夹(包含web.config的文件夹),按住Shift键右击,选择“在此处打开命令窗口”。
  4. 在命令窗口中,键入以下命令:
    ..\packages\Owinhost<Version>\tools\Owinhost.exe
    

    命令窗口显示如下:
    OWIN启动类检测-程序旅途

  5. 启动浏览器,输入地址:http://localhost:5000/
    OWIN启动类检测-程序旅途
    OwinHost遵循上面列出的约定。
  6. 在命令窗口中,按回车键退出OwinHost。
  7. 在ProductionStartup类中,添加下面的OwinStartup特性,并指定一个友好的名称:ProductionConfiguration,(不要忘记编译项目)。
    [assembly: OwinStartup("ProductionConfiguration", typeof(StartupDemo.ProductionStartup))]
    
  8. 在命令窗口中键入:
    ..\packages\Owinhost.2.1.0\tools\Owinhost.exe ProductionConfiguration
    

    Production启动类被加载。
    OWIN启动类检测-程序旅途
    我们的程序有多个启动类,在这个例子中,哪个启动类被加载推迟到了运行时。

  9. 测试下面的运行时启动项:
    ..\packages\Owinhost.2.1.0\tools\Owinhost.exe StartupDemo.TestStartup
    ..\packages\Owinhost.2.1.0\tools\Owinhost.exe "StartupDemo.TestStartup,StartupDemo"
    ..\packages\Owinhost.2.1.0\tools\Owinhost.exe StartupDemo.TestStartup.Configuration
    ..\packages\Owinhost.2.1.0\tools\Owinhost.exe "StartupDemo.TestStartup.Configuration,StartupDemo"