ASP.NET開發規范:OWIN
今天投簡歷 准備面試了...
本節目錄:
OWIN(Open Web Interface For .Net)
OWIN是.Net開源社區借鑒Ruby而制定的.Net Web開發架構,有着非常簡單的規范定義,目標是用於解耦Web Server和Web Application.
ASP.NET的局限性
ASP.NET核心是System.Web,而System.Web緊耦合IIS.IIS綁定在Windows OS上,所以ASP.NET 無法跨平台.
System.Web是.NET Framework重要組成,所以System.Web更新需要等待.NET的發布
OWIN定義了4層:
2
Host:主要負責應用程序的配置和啟動進程,包括初始化OWIN Pipeline、運行Server。
Server:綁定套接字並監聽的HTTP請求然后將Request和Response的Body、Header封裝成符合OWIN規范的字典並發送到OWIN Middleware Pipeline中
Middleware:稱之為中間件、組件,位於Server與Application之間,用來處理發送到Pipeline中的請求
Application:這是具體的應用程序代碼,只不過我們將他們注冊到OWIN Pipeline中去處理HTTP 請求,成為OWIN管道的一部分
OWIN接口
Func<IDictionary<string, object>, Task>;
用於Server和Middleware的交互。他並不是嚴格意義上的接口,而是一個委托並且每個OWIN中間件組件必須提供。
其中參數類型為IDictionary<string,object>的變量為環境變量
微軟引入並推廣OWIN,同時依照OWIN規范,實現了Katana。
Host
宿主只是一個進程,是整個OWIN程序的載體。這個宿主可以是IIS, IIS Express, Console, Windows Service等。
Katana為我們提供了3中選擇:
- IIS / ASP.NET :使用IIS是最簡單和向后兼容方式,在這種場景中OWIN Pipeline通過標准的HttpModule和HttpHandler啟動。使用此Host你必須使用System.Web作為OWIN Server
- Self-Host :如果你想要使用其他Server來替換掉System.Web,並且可以有更多的控制權,可以選擇創建一個自定義宿主,如使用Windows Service、控制台應用程序、Winform來承載Server
- OwinHost :也可以使用Katana提供的OwinHost.exe:他是一個命令行應用程序,運行在項目的根部,啟動HttpListener Server並找到基於約束的Startup啟動項
Server
負責綁定到 TCP 端口,監聽端口發送過來的請求,同時將請求的信息依照OWIN規范,包裝成字典格式,傳遞到下層的Middleware
Katana對OWIN Server的實現分為如下幾類:
- System.Web:當使用IIS作為Host時,System.Web把自己注冊為HttpModule和HttpHandler並且處理發送給IIS的請求(Microsoft.Owin.Host.SystemWeb)
- HttpListener:這是OwinHost.exe和自定義Host默認的Server。(Microsoft.Owin.Host.HttpListener)
- WebListener:這是ASP.NET vNext默認的輕量級Server,他目前無法使用在Katana中
Middleware
這是為組成 OWIN 管道中的組件。
Middleware可以理解為提供Func<IDictionary<string, object>, Task>接口的組件。
Katana提供了一個OwinMiddleware基類更加方便我們繼承來實現OWIN Middleware.
Application
具體的代碼實現,比如ASP.NET Web API、SignalR具體代碼的實現。
事實上,對於這些類型的應用程序,Katana 組件只需使用一個小的配置類即可見。
IIS-Host
新建一個空的Web項目,Nuget引用Microsoft.Owin.Host.SystemWeb
創建Startup類
|
1
2
3
4
5
6
7
8
9
10
11
|
public
class
Startup
{
public
void
Configuration(IAppBuilder app)
{
app.Run(context =>
{
context.Response.ContentType =
"text/plain"
;
return
context.Response.WriteAsync(
"Hello World!"
);
});
}
}
|
訪問項目地址:http://localhost:xx
Self-Host
新建控制台項目,Nuget引用Microsoft.Owin.SelfHost
Main方法
|
1
2
3
4
|
創建Startup類
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class
Startup
{
public
void
Configuration(IAppBuilder app)
{
#if DEBUG
//診斷
app.UseErrorPage();
#endif
//歡迎頁
//app.UseWelcomePage("/");
app.Run(x=>x.Response.WriteAsync(
"hello world"
));
}
}
|
訪問地址:http://localhost:12345
OWIN-Host
新建類庫項目,Nuget引用OwinHost
創建Startup類(需要程序集Owin和Microsoft.Owin)
|
1
2
3
4
5
6
7
8
9
10
11
|
public
class
Startup
{
public
void
Configuration(IAppBuilder app)
{
app.Run(context =>
{
context.Response.ContentType =
"text/plain"
;
return
context.Response.WriteAsync(
"Hello World!"
);
});
}
}
|
OwinHost.exe
這里需要注意
- Nuget下載完,OwinHost.exe會在package文件夾里
- OwinHost.exe會加載./bin文件夾下的程序集作為server assembly
所以我們將這OwinHost.exe3個文件移動到
=>
另外將Debug或者Release文件夾下的文件移動到bin文件夾下

cmd運行OwinHost.exe

訪問:http://localhost:5000/
Middleware非常類似於HttpModule,會注冊到Owin的pipeline中執行代碼.
繼承OwinMiddleware
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
HelloMiddlerware : OwinMiddleware
{
public
HelloMiddlerware(OwinMiddleware next)
:
base
(next)
{
}
public
override
Task Invoke(IOwinContext context)
{
context.Response.Write(
"hello"
+DateTime.Now);<br>
//管道繼續往下走
return
Next.Invoke(context);
}
}
|
Startup
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
Startup
{
public
void
Configuration(IAppBuilder app)
{
// 有關如何配置應用程序的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkID=316888
//管線自由組合
app.Use<HelloMiddlerware>();
//Run是插入一個中間件,並終止繼續往下流
app.Run(x => x.Response.WriteAsync(
"good"
));
//此中間件將不執行
app.Use<HelloMiddlerware>();
}
}
|
來看一下組件的執行順序
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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/>"
));
}
}
|
瀏覽結果:

擴展
Startup類如何被關聯
1.默認名稱匹配
可以定義Startup.cs類,只要這個類的namespace和Assembly的名稱相同。那么,這個Startup.cs中的Configuration方法,就會在OWIN管道初始化的時候執行。
2.使用OwinStartup Attribute
這就是我們例子中使用的方式,直接指定哪個具體類是Startup類。
3.在配置文件的appSetting 節點設置
|
1
2
3
|
<appSettings>
<add key=
"owin:appStartup"
value=
"StartupDemo.ProductionStartup"
/>
</appSettings>
|
Pipeline
Owin的pipeline在IIS Host上本質是注冊到Httpapplication的pipeline上.
如:app.UseStageMarker(PipelineStage.Authenticate);
本文參考:
http://www.cnblogs.com/JustRun1983/p/3955238.html
Katana:http://www.asp.net/aspnet/overview/owin-and-katana/an-overview-of-project-katana
