首页 > 代码库 > OWIN

OWIN

OWIN

OWIN的全称是Open Web Interface For .Net。

OWIN提供的只是一种规范,而没有具体实现。其目的是在web服务器和应用程序组件之间隔离出一个抽象层,使它们之间解耦。

应用程序委托和环境字典

OWIN将服务器与应用程序之间的交互减少到一小部分类型和单个函数签名,这个函数签名被称为应用程序委托(即 AppFunc):

using AppFunc = Func<IDictionary<string, object>, Task>;

基于 OWIN 的应用程序中的每个组件都向服务器提供应用程序委托。 然后,这些组件链接成一个管道,基于 OWIN 的服务器将会向该管道推送请求。 为了更有效地使用资源,管道中的所有组件都应该是异步的,这体现在返回 Task 对象的应用程序委托中。

 

一个符合OWIN的web服务器,需要将请求信息(应用程序状态、请求状态和服务器状态等所有相关信息)包装到一个字典里(应用程序委托上指定的 IDictionary<string, object>,这种数据结构称为环境字典),从而使得许多不同的框架和组件作者可以在一个 OWIN 管道中进行互操作,而不必强制实施对特定 .NET 对象模型的协议。

虽然任何键/值数据都可以插入到环境字典中,但 OWIN 规范为某些 HTTP 核心元素定义了键: 

键名称值说明
"owin.RequestBody"一个带有请求正文(如果有)的流。如果没有请求正文,Stream.Null 可以用作占位符。
"owin.RequestHeaders"请求标头的 IDictionary<string, string[]>。
"owin.RequestMethod"一个包含请求的 HTTP 请求方法的字符串(例如 GET 和 POST)。
"owin.RequestPath"一个包含请求路径的字符串。 此路径必须是应用程序委托的“根”的相对路径。
"owin.RequestPathBase"一个字符串,包含对应于应用程序委托的“根”的请求路径部分。
"owin.RequestProtocol"一个包含协议名称和版本的字符串(例如 HTTP/1.0 或 HTTP/1.1)。
"owin.RequestQueryString"一个字符串,包含 HTTP 请求 URI 的查询字符串组成部分,不带前导“?”(例如 foo=bar&baz=quux)。 该值可以是空字符串。
"owin.RequestScheme"一个字符串,包含用于请求的 URI 方案(例如 HTTP 或 HTTPS)。

 

随着请求在OWIN管道中流动,每个中间件(Middleware,集成到管道中的组件或应用程序)所要做的就是读取、修改这个字典的数据。最后,Web服务器得到这个层层处理过的字典,然后输出网页到客户端。

 

与ASP.NET管道相比,OWIN规范非常简洁,且并没有引用.Net Framework中的System.Web.dll。

   1. 新的组件能够非常简单的开发和应用
   2. 程序能够简便地在host和OS上迁移

Katana 项目

 技术分享

技术分享

——————

Demo尝试

默认的 Katana 主机会在 /bin 文件夹中查找程序集。所以首先建立一个空的web应用程序。因为Web应用程序默认会将编译的程序集直接放在 /bin 文件夹而不是 /bin/debug 文件夹中。

技术分享

删除无关文件,引入OWIN的支持包

技术分享

添加Startup启动类

Startup类的作用是用来初始化OWIN管道,这里,我们添加和初始化OWIN管道中的Middleware.

技术分享

 在Startup.Configuration方法中,添加如下代码:

public void Configuration(IAppBuilder app){    // New code:    app.Run(context =>    {        context.Response.ContentType = "text/plain";        return context.Response.WriteAsync("Hello, world.");    });}

上面的代码做的事情,就是把一个简单的Middleware注册到OWIN管道中。

其中context的类型是IOwinContext:

public interface IOwinContext{    //     Gets the Authentication middleware functionality available on the current request.    IAuthenticationManager Authentication { get; }    //     Gets the OWIN environment.    IDictionary<string, object> Environment { get; }    //     Gets a wrapper exposing request specific properties.    IOwinRequest Request { get; }    //     Gets a wrapper exposing response specific properties.    IOwinResponse Response { get; }    //     Gets or sets the host.TraceOutput environment value.    TextWriter TraceOutput { get; set; }    //     Gets a value from the OWIN environment, or returns default(T) if not present.    T Get<T>(string key);    //     Sets the given key and value in the OWIN environment.    IOwinContext Set<T>(string key, T value);}

 运行结果:

技术分享

改用其他形式的Host和Server

上例中IIS同时充当了Host和Server的角色, 

首先创建一个简单的Console应用程序,用Nuget添加Microsoft.Owin.SelfHost

技术分享

 

以同样的方式添加Startup启动类

将控制台程序改造为Host

class Program{    static void Main(string[] args)    {        using (Microsoft.Owin.Hosting.WebApp.Start<Startup1>("http://localhost:9000"))        {            Console.WriteLine("Press [enter] to quit...");            Console.ReadLine();        }    }}

运行结果:

技术分享

PS:

无论使用IIS, IIS Express还是OWIN Host, 微软在这些Host上实现的Service都会依照特定的规则来寻找到Startup类,执行Configuration方法,注册Middleware。

默认名称匹配
可以定义Startup.cs类,只要这个类的namespace和Assembly的名称相同。那么,这个Startup.cs中的Configuration方法,就会在OWIN管道初始化的时候执行。

使用OwinStartup Attribute
直接指定哪个具体类是Startup类。

在配置文件的appSetting 节点设置

<appSettings>    <add key="owin:appStartup" value="http://www.mamicode.com/StartupDemo.ProductionStartup" /></appSettings>

 

 Web Form和MVC依赖于System.Web.dll中的很多类型。而在OWIN管道中,是无法提供这些依赖的

OWIN