Kantana是遵守OWIN规范的应用框架,下面四层架构也正是OWIN的规范
架构
Host
宿主层,是OWIN程序的载体,这个宿主可以是IIS, IIS Express, Console, Windows Service等。
Katana通过在IIS上构建一个类似适配器,使得OWIN管道能够运行在IIS上,同时Katana也已经提供了一个可以直接运行Host——OwinHost.exe
作用
1. 管理底层进程
2. 当有请求过来的时候,选择相应的Server和构建OWIN管道处理请求。
Server
负责绑定到 TCP 端口,监听端口发送过来的请求,同时将请求的信息依照OWIN规范,包装成字典格式,传递到下层的Middleware.
IIS既可以作为Host层,也可以作为Server层
Microsoft.Owin.Host.SystemWeb
这个是用来对应IIS的,由于IIS既是Host,又是Server. 所以这个Server实现的作用是注册ASP.NET HttpModule和HttpHandler阻断原有的处理流程,转而把请求发送到OWIN管道中处理
Microsoft.Owin.Host.HttpListener
使用HttpListener打开Socket端口,监听请求,然后将请求包装发送到OWIN管道中处理。
字典: OWIN将web应用中的request, response, session, cookie等所有相关信息都简化成下面的字典
"owin.RequestBody"
请求报文体数据流. 如果没有报文体使用Stream.Null作为占位符."owin.RequestHeaders"
一个IDictionary<string, string[]><string, string[]="">
类型请求头字典. See Headers."owin.RequestMethod"
Astring
containing the HTTP request method of the request (e.g.,"GET"
,"POST"
)."owin.RequestPath"
Astring
containing the request path. The path MUST be relative to the "root" of the application delegate; see Paths."owin.RequestPathBase"
Astring
containing the portion of the request path corresponding to the "root" of the application delegate; see Paths."owin.RequestProtocol"
Astring
containing the protocol name and version (e.g."
HTTP/1.0"
or"
HTTP/1.1"
)."owin.RequestQueryString"
Astring
containing the query string component of the HTTP request URI, without the leading “?” (e.g.,"foo=bar&baz=quux"
). The value may be an empty string."owin.RequestScheme"
Astring
containing the URI scheme used for the request (e.g.,"http"
,"https"
); see URI Scheme.
Middleware
类似Asp.Net的Module的职责,OWIN 管道中的组件,Katana提供了一个OwinMiddleware基类更加方便我们继承来实现OWIN Middleware.
Application
应用程序代码
Owin核心定义
OWIN将web应用中的request, response, session, cookie等所有相关信息都简化成字典(表见上)
这是所有运行在OWIN协议下的组件都需要遵循的接口Func<IDictionary<string, object>, Task>;
简单的Web Host Demo
上面提到了Kantana支持多种宿主,这里只介绍Web Host
根据Owin协议,Middleware需要通过Func<IDictionary<string, object>, Task>
添加
在空的MVC5项目中右键添加项可以创建一个Owin Startup类
[assembly: OwinStartup(typeof(OwinDemo.Startup))]
namespace OwinDemo
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888
app.Run(context =>
{
context.Response.ContentType = "text/plain";
return context.Response.WriteAsync("Hello, world.");
});
}
}
}
Startup类可以理解为传统的Global.asax
上面代码演示了注册一个Middleware到Owin管道,app.Run的方法签名如下
public static void Run(this IAppBuilder app, Func<IOwinContext, Task> handler);
这是个扩展方法,它有一个委托参数,正是Owin定义要求的那个委托,利用他我们能给管道注册Middleware
而委托参数是一个IOwinContext接口,他的成员如下
public interface IOwinContext
{
IAuthenticationManager Authentication { get; }
IDictionary<string, object> Environment { get; }
IOwinRequest Request { get; }
IOwinResponse Response { get; }
TextWriter TraceOutput { get; set; }
T Get<T>(string key);
IOwinContext Set<T>(string key, T value);
}
可以看到Http请求中要用到的东西都能通过这个接口获得.另外这次请求相关的数据都封装成字典保存在Environment
上述代码中的
[assembly: OwinStartup(typeof(OwinDemo.Startup))]
是用来设置Owin启动类更多的设置方法看下文
Middleware
我们通过集成OwinMiddleware来编写自己的中间件
public class HelloWorldMiddleware : OwinMiddleware
{
public HelloWorldMiddleware(OwinMiddleware next) : base(next)
{
}
public override Task Invoke(IOwinContext context)
{
var response = "Hello World! It is " + DateTime.Now;
context.Response.Write(response);
return Next.Invoke(context);
}
}?
中间件的执行过程根据Startup类中注册的顺序.上述代码的Next.Invoke
代表执行下一个中间件
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use((x, next) =>
{
x.Response.ContentType = "text/html";
return next.Invoke();
});
app.Use((x, next) =>
{
x.Response.WriteAsync("1 Before");
next.Invoke();
return x.Response.WriteAsync("1 After");
});
app.Use((x, next) =>
{
x.Response.WriteAsync("2 Before");
next.Invoke();
return x.Response.WriteAsync("2 After");
});
app.Run(x => x.Response.WriteAsync("<br/>hello world<br/>"));
}
}
注意app.Use是添加中间件,而app.Run仅仅只是执行,app.Run后面的代码是不执行的,也就是在app.Run后面使用app.Use是无效的
Owin启动
一.约定
Kantana寻找一个名字程序集名称或全局命名空间匹配的命名空间中的 Startup
类
二.OwinStartup 特性
在类名上面添加
1 [assembly:OwinStartup(typeof(startClassType))]
三.使用配置文件
在web.config中的appSetting添加相关配置
指定类名
1 <addkey="owin:appStartup"value="StartupDemo.ProductionStartup"/>
指定类名和程序集
1 <addkey="owin:appStartup"value="StartupDemo.ProductionStartup,StartupDemo"/>
带friendlyname的配置方式
1 <addkey="owin:appStartup"value="ProductionConfiguration"/>
这种方式要求类名上面也要使用特性标签,并注明friendlyname
1 [assembly:OwinStartup("ProductionConfiguration",typeof(StartupDemo.ProductionStartup2))]
摘抄至
http://www.asp.net/aspnet/overview/owin-and-katana
http://www.cnblogs.com/JustRun1983/p/3967757.html
http://www.cnblogs.com/neverc/p/4864414.html