下一代Asp.net开发规范OWIN(3)—— Middleware
Middleware是OWIN管道的基本組成單元,最后拼接的OWIN管道來處理客戶端請求,輸出網頁。這篇文章,首先看看Web Form, MVC, Web API如何結合OWIN使用。 然后將如何編寫Middleware和編寫一個具體的Cache Middleware.
閱讀目錄:
一. 原有的Web Form, MVC項目如何結合OWIN?
???? 1.1 通過路由配置,將程序分成多個部分,一些部分由Asp.net Web Form或者MVC處理,另外一部分由OWIN管道處理。
???? 1.2 在Web Form, MVC之前插入OWIN
三. 自定義Cache Middleware
???? 3.1 HelloWorld Middleware
???? 3.2 Cache Middleware
四,總結
一,原有的Web Form, MVC項目如何結合OWIN?
壞消息,非常抱歉,盡管OWIN是革命性的,但是Web Form和MVC現在還不能作為一個中間件集成到OWIN管道中。原因在第一篇中Asp.net的歷史中有分析過,原因就是Web Form和MVC依賴于System.Web.dll中的很多類型。而在OWIN管道中,是無法提供這些依賴的。不過好消息是,在Asp.net vNext中,將會徹底告別System.Web.dll依賴, 那個時候,Asp.net vNext將是集大成者。聽說vNext項目組正在和Mono團隊一起工作,使得Asp.net vNext開發的項目能夠在*nix, osx系統上運行。
那么在當前的情況下,OWIN和Web Form, MVC的結合開發一般是兩種形式:
1. 通過路由配置,將程序分成多個部分,一些部分由Asp.net Web Form或者MVC處理,另外一部分由OWIN管道處理。
// How to hook OWIN pipelines into the normal Asp.Net route table side by side with other components. protected void Application_Start(object sender, EventArgs e) {//owin開頭的訪問路徑將會發送到startup.cs初始化的OWIN管道處理RouteTable.Routes.MapOwinPath("/owin");//special開頭的訪問路徑將會由OwinApp2管道來處理 RouteTable.Routes.MapOwinPath("/special", app =>{app.Run(OwinApp2.Invoke);}); }如上面代碼,在Application_Start函數或者路由配置函數中,分別為/owin路徑和/special配置了不同的OWIN管道。
完整的代碼,請移步這里http://aspnet.codeplex.com/sourcecontrol/latest#Samples/Katana/AspNetRoutes/Global.asax.cs
2. 在Web Form, MVC之前插入OWIN
在Web Form和MVC項目中,也可以添加Startup.cs, 指定成為OWIN的初始化類型,那么請求會先經過OWIN管道處理,最后轉向Web Form或者MVC程序。這種方式,常常用來配置log, authentication, cache等等這些Middleware.
二,Web API以Middleware注冊到OWIN管道
Web API由于無任何依賴于System.web.dll, 所以Web API可以作為Middleware注冊到OWIN管道中。
具體方法如下:
public class Startup{// Invoked once at startup to configure your application.public void Configuration(IAppBuilder builder){HttpConfiguration config = new HttpConfiguration();config.Routes.MapHttpRoute("Default", "api/{controller}/{customerID}", new { controller = "Customer", customerID = RouteParameter.Optional });//定義web api route//xml格式輸出結果 config.Formatters.XmlFormatter.UseXmlSerializer = true;config.Formatters.Remove(config.Formatters.JsonFormatter);// config.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;//將web api以Middleware注冊到OWIN管道中 builder.UseWebApi(config);}}三,自定義Cache Middleware
3.1 HelloWorld Middleware
先建一個Middleware, 通過繼承OwinMiddleware基類。這個Middleware的功能非常簡單,就是打印當前的系統時間。
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);} }將該Middleware注冊到OWIN管道后,執行得到的網頁:
只要我們不斷的刷新網頁,每次顯示的時間都會不同,因為每次都會重新讀取系統時間,重新呈現頁面。
3.2 Cache Middleware
實現cache middleware的思路比較簡單,以訪問的Url為key, 以輸出的內容為value。第一次訪問的時候,會緩存下來輸出的內容,在下次訪問的時候,將直接返回緩存的內容,而不是重新生成。具體代碼如下:
public class CacheMiddleware : OwinMiddleware{private readonly IDictionary<string, CacheItem> _responseCache = new Dictionary<string, CacheItem>(); //Cache存儲的字典public CacheMiddleware(OwinMiddleware next): base(next){}public override Task Invoke(IOwinContext context){context.Environment["caching.addToCache"] = new Action<IOwinContext, string, TimeSpan>(AddToCache);var path = context.Request.Path.Value;//如果訪問的路徑沒有緩存,就傳遞到OWIN管道的下一層中處理if (!_responseCache.ContainsKey(path)) {return Next.Invoke(context);}var cacheItem = _responseCache[path];//檢查緩存是否到期if (cacheItem.ExpiryTime <= DateTime.Now){_responseCache.Remove(path);return Next.Invoke(context);}//直接從緩存中輸出,而不是重新render頁面 context.Response.Write(cacheItem.Response);return Task.FromResult(0);}//添加cache的方法,將會以委托的方式存放到OWIN管道字典中,這樣任何OWIN的Middleware都能夠調用,從而保存數據到緩存public void AddToCache(IOwinContext context, string response, TimeSpan cacheDuration) {_responseCache[context.Request.Path.Value] = new CacheItem { Response = response, ExpiryTime = DateTime.Now + cacheDuration };}private class CacheItem{public string Response { get; set; }//保存緩存的內容public DateTime ExpiryTime { get; set; }//確定緩存的時間 }} View Code接下來,我們要改造HelloWorldMiddleware, 在HelloWorldMiddleware輸出后,我們把輸出的內容保存到Cache中。具體代碼如下:
public class HelloWorldMiddleware : OwinMiddleware{public HelloWorldMiddleware(OwinMiddleware next) : base(next){}public override Task Invoke(IOwinContext context){var response = "Hello World! It is " + DateTime.Now;if (context.Environment.ContainsKey("caching.addToCache"))//這里直接從OWIN管道的字典中,檢查是否有add cache, 如果存在,就將輸出內容緩存到cache中,過期時間為10分鐘。 {var addToCache = (Action<IOwinContext, string, TimeSpan>)context.Environment["caching.addToCache"];addToCache(context, response, TimeSpan.FromMinutes(10));}context.Response.Write(response);return Task.FromResult(0);}} View Code最后,將CacheMiddleware添加到OWIN管道中發揮作用,注意注冊管道的順序問題,Middleware是一定要在HelloWorldMiddleware之前的。
public class Startup {public void Configuration(IAppBuilder app){app.Use<CacheMiddleware>();app.Use<HelloWorldMiddleware>();} }四,總結
通過上面的示例,希望對大家如何編寫Middleware有些基本的概念。
OWIN的優勢在上面的例子中應該有些體現,就是Middleware之間通過數據和行為規范, 大家可以一起無縫地協同工作,任何第三方的Middleware都可以非常簡單的集成到OWIN管道中,這應該是OWIN最大的魅力所在,開放的魅力。
同時, OWIN的目標是將Web Form, MVC, Web API統一到一個大的平臺下,這將更加有助于混合編程。
轉載于:https://www.cnblogs.com/JustRun1983/p/3967757.html
總結
以上是生活随笔為你收集整理的下一代Asp.net开发规范OWIN(3)—— Middleware的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL*Plus中替换变量与定义变量
- 下一篇: UltraEdit常用配置搭建Java/