710官方网站想开了万生出引力。的確不容许創造出10%上述的人造智能來。HttpModule/HttpHandler 從 ASP.NET 1.0 開始就存在於整個 ASP.NET

昨晚看BBC的关于大脑的科教片,讲到了灵感一般在身心放松的条件下闪现。例如:牛顿于果园里,看到苹果落地,想到了万闹引力;伽利略在教堂想到钟摆;瓦特看开水及开壶盖,想到了蒸汽的力量,发明蒸汽机……

《机器人获选亚洲周刊风云人物》(來源《聯合早報》)。

HttpModule/HttpHandler 從 ASP.NET 1.0 開始就存於整個 ASP.NET
的結構中,只不過一般的使用者比較少注意到它們,因此它們被应用的頻率和高階層的
web form 來比就少了很多.然而以 ASP.NET Core
開始,你就坏難不會注意到它們了,因為它們就一直是於你所而執行的程式碼,直接就是扣留之顶,所以不注意啊十分了.這一篇稿子以說明在
ASP.NET Core 中凡是怎麼使用類似像于原先版本 HttpModule 的功能,在 ASP.NET
Core 裡,它不再让 HttpModule/HttpHandler 了,有矣初的讳,叫
Middleware.

作程序员,有时,也得以借鉴一下。
以下是自身呢者拼凑的仿:
再也多的关于研究大脑科教片的笔记,见http://www.123de6.cn直达的博客栏目

單純標題就可使她让自己收入來了。但對於標題所陈述得事情,我還能說點什麽呢?好像也非克重复說點什麽了。畢竟我还要不是評委。

HttpModule

倘你曾經或現在在干活於 HttpModule,那表示您對 4.x 版前之 ASP.NET
life cycle 比較清楚了.有關 ASP.NET life cycle ,可以參考 ASP.NET life
cycle – https://msdn.microsoft.com/en-us/library/ms178473(v=vs.85).aspx

自先分享自己前用 HttpModule 的經驗,大約十几近年前横,當時剛好是 ASP.NET
2.0 將要上市之時間,所以那時候很多底專案還是用 ASP.NET 1.0 來寫. 因為
ASP.NET 1.0 並還沒有完整的 access control 機制,只有較為單純的 windows
authentication 和 form authentication 等,而于 authorization 在 ASP.NET
1.0 中还是空荡荡的.因此,當時生個同事就动用了 HttpModule 自行處理了
authorization 的部份,也就是說當使用者透過了 Windos authentication/Form
authentication 之後,就可知在 HttpContext 中取 username,同時在
HttpContext 中呢隐含該連線要去的 web form (.aspx),所以当那么一個
HttpModule
之中就得驗證該使用者是否生權限存取該網頁.透過存取資料庫中之資料來做為驗證,一旦發現無權限時尽管會把該
http request 重新導向到某一個顯示錯誤訊息的網頁.透過這樣做的好處就是
authorization 的行事便无须在每一個網頁 (*.aspx)
中來檢查,大大地減少了另外工程師的負擔,讓其他工程師只要專注在該網頁所待的力量即可,不用擔心權限處理的事情.後來,我管這個想法再包裝起來,然後放在
codeplex 上做為一個 open source 讓所有人数得以來參考,其網址是
http://aspnetaccesscontrol.codeplex.com,後來因為 ASP.NET
有較完整的存取控制機制了,因此從 2009 年之後我虽重新为沒繼續維護那同样項
open source project.

以同样不过生秒针的手表,随着秒针的跳动数数,等公往往数底进度以及秒针跳动速度相适合时,紧张就是足以就缓解。
原理非常简短,紧张时,心跳速度必然加快,当注意力集中在秒针时,心跳速度放缓了,生理之状态放松了,心理呢会随之而放松。

還好,文中還是有些字值得自己寫上一兩句子之。“人类对好大脑的认识不至10%,10%创造出的机不可能超越人类。”這是馬雲先生的原話。他的確相當樂觀。在自家看來是樂觀過頭了咔嚓。

Middleware

以 ASP.NET Core 中,由於整個架構和程式都是再度來了,所以 HttpModule
自然为不怕非有了.但是相似的效力還是有的,它的名给
Middleware.跟以前不同的凡于 ASP.NET Core 中若必會看到 Middleware
的存,因為現在各级一個服務都是因此 middleware 的道呈現在 ASP.NET Core 的
pipleline 中.不儘如此,middleware 就得更彈性易用,跟原先 HttpModule
比起來方便多了.首先,先來看什麼是 middleware.

 1         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 2         {
 3             loggerFactory.AddConsole(Configuration.GetSection("Logging"));
 4             loggerFactory.AddDebug();
 5 
 6             app.UseStaticFiles();
 7  
 8             app.UseMvc(routes =>
 9             {
10                 routes.MapRoute("default","{controller=Home}/{action=Index}/{id?}");
11             });
12         }

如果你早就試用過或押過 ASP.NET Core 的測試版,相信你對 Startup.cs
並不會陌生.在 Startup.cs 裡面有一個 Configure() mehtod
就是用來定義要运那些 middleware.上面的事例使用了兩個
middleware,一個凡 UseStaticFiles,另一個是 UseMvc,這兩個都是內建之
middleware,UseStaticFiles 是会讓 http request 存取網站上之檔案,而
UseMvc,顧名思義就掌握這是啟用 MVC routing 機制.因為有矣這兩個
middleware 的进入,所以若的網站才会发生 MVC routing
的效力跟存取靜態檔案的力量,如果您管 UseMvc 拿掉的話,那麼 MVC routing
機制就不會存在,因此你打 http://website/\[Controller\]/\[Action\]
這類的網址時都未會有結果.

自己觉着这法子充分好,实施起来格外便利也异常简单,而且有些花工夫,很符合临考前下。

誠然,人類祇認識自己大腦10%,人工智能也是根據這已經認識的10%創造出來的。按數學角度計算,的確不容许創造出10%之上之人工智能來。從這個角度达了解馬先生之話,十分正確。不過,這些是純數學概念的知晓而已。

與 HttpModule 不同處

动用 HttpModule 時,我們需要以適當的地方召开適當的作业,比如,要召开
authorization 的話就最为好以 HttpModule 定義好之 Authorization 事件
(AuthorizatRequest) 裡面來做這件事.從 ASP.NET life cycle
的文书裡可以查看及 HttpModule
定義了那些事件,每一個事变都有特別的意义,因此開發者需要健全了解後还來選擇適當的事件.Middleware
的好處就是沒有這些複雜的轩然大波定義,因此可以讓開發者方便地發揮,可以活动設計自己的機制.

 

首先,人類對自身大腦的開發不多,如果本身沒有記錯,現在之总人口對大腦的開發祇有20%横,也即說,人還可以繼續開發剩餘的80%底空白。從數字來說,好像还能够表明人工智能無法超越人類。可是,不要忘記一個事實,從人類的產生到今日,少說也发幾千年,多則上百萬年,人類開發自己大腦的快吗便緩慢的到達20%;可人工智能的出現纔短短幾十年(從圖靈開始算),能力已經比肩人類。這種速度之别實在不是一般。人類何來的底氣,如此樂觀?

Middleware 流程

https://docs.asp.net/en/latest/fundamentals/middleware.html
這篇文书被說明了主导的 middleware 概念,目前這些 asp.net docs
裡面有不少的內容都是社群成員所貢獻的,middleware
這一篇內容就是.在這篇文书裡有一個簡易的流程圖可以为此來說明 middleware
的執行過程.

這個流程圖案說明的凡于 ASP.NET runtime 時期 middleware 的執行過程.以
middleware 裡一定要是定義一個 method 叫 Invoke(),因為這是讓 engine
可以呼叫該 middleware 的進入點.Middleware 裡面所急需執行的邏輯就位于
Invoke() 裡面,同時 Invoke() 裡面還需要呼叫下一個
middleware.因此,執行的過程就比如這張圖的內容.Middleware 之間一定要是傳送
HttpContext,除此之外,也可自行定義傳送其他的參數,這部份比原先的
HttpModule 方便多了.所以當 HTTP request 進來之後,engine
就會把呼叫第一個 middleware 的 Invoke(),同時把 HttpContext
傳送過去,然後第一個 middleware 可以更接著呼叫第二個 middleware 的
Invoke(),同時再管 HttpContext 傳送過去,一直顶最後一個 middleware 的
Invoke() 結束之後,整個 HttpContext 的內容可能还會在 middleware
裡面做新增或改變,最後再按照整個原先的 call stack 從最後一個 middleware
回到第一個 middleware,然後再透過 engine 回傳給 client
端.接下來,直接來看一個簡單的例子就是能讓你了解再細節.

看悟式.這种灵感形式之起不是借助於外界信息之振奋,
而是通过脑内在的清醒, 通过内部"思想之闪耀".例如, 爱因斯坦于1895
年起便起思索: "如果自己以光速追踪一修光线, 我会看到啊?
"他一再思考這个问题, 但很多年尚无解决.1905 年的一样上早上,
在起床时他猛然想到: 对於一个观察者來說是还要的鲜单事件,
对别的观察者來說就非必然是以的.他飞发现及這是单突破口,
并牢牢吸引了這一"灵感的闪亮",
后來只所以了五六个礼拜的年月就是写成了提出狭义相对论的知名论文.

从,也是最關鍵的,人類之間存在著個體能力的差別,有些人是這個能力強,別人則是那個能力強。不過,人工智能則是可以凑合各能力成於一身,如此一來,是否已經在力量上跳了10%乎?雖然,這些能力還都在人類認識的10%之內。

撰寫簡單的 Middleware

下的程式碼是一個分外簡單的 middleware

 1     public class SampleMiddleware
 2     {
 3         private readonly RequestDelegate _next;
 4 
 5         public SampleMiddleware(RequestDelegate next)
 6         {
 7             _next = next;
 8         }
 9 
10         public async Task Invoke(HttpContext context)
11         {
12             if (string.IsNullOrEmpty(context.User.Identity.Name))
13             {
14                 context.Response.Redirect("/NoName.html");
15                 return;
16             }
17             await _next.Invoke(context);
18         }
19     }

這一個 middleware 的名字被 SampleMiddleware.它起一個 constructor 和一個
Invoke() method,而 Invoke() 只收到一個參數 HttpContext._next
代表的凡一個特別設計的東西,叫 RequestDelegate,它是一個 delegate
用來代表下一個 middleware 是誰,所以于 constructor 裡就要拿下一個
middleware delegate 給帶進來.也許你會覺得奇怪,執行的過程中這個
middleware 怎麼會知道下一個 middleware 是誰呢 ? 這部份稍後會說明.

在 Invoke() 裡面,在 await _next.Invoke() 之前还是当呼唤下一個
middleware 時會執行的程式碼,從上面流程圖來看之話就是出于左自右的方式.
await _next.Invoke()
之後的程式碼是不怕是流程圖上是因为右至右的可行性,因此,透過這樣簡單的設計,開發者就会挺明確地决定什麼樣的程式碼要先开或後做了.在
SampleMiddleware 之中,我单开了一個老大簡單的動作,如果 username
是空荡荡的話,就將該連線重新導向到 NoName.html 然後中斷 middleware
的執行.

為了要讓這個 middleware 可以讓 ApplicationBuilder
來使用,我們另外建立以下的程式碼

1     public static partial class MiddlewareExtensions
2     {
3         public static IApplicationBuilder UseSampleMiddleware(this IApplicationBuilder builder)
4         {
5             return builder.UseMiddleware<SampleMiddleware>();
6         }
7     }

透過 C# extension method,建立
UseSampleMiddleware(),而裡面的程式碼就是讓 ApplicationBuilder 去讀
SampleMiddleware.

接著回到 Startup.cs,在 Configure() 裡把 SampleMiddleware 加入到程式的
pipeline.

 1         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 2         {
 3             loggerFactory.AddConsole(Configuration.GetSection("Logging"));
 4             loggerFactory.AddDebug();
 5 
 6             app.UseStaticFiles();
 7 
 8             app.UseSampleMiddleware();   // <-- SampleMiddleware
 9 
10             app.UseMvc(routes =>
11             {
12                 routes.MapRoute("default","{controller=Home}/{action=Index}/{id?}");
13             });
14         }

把 SampleMiddleware 放在 UseStaticFiles 和 UseMvc 之間,也就是說在 http
request 還沒進入到 MVC routing 之前,就會先檢查 HttpContext
裡面是匪是起空落落的
username.很顯然一定會是的,因為我並沒有加入其他使用者驗證的程式在這專案裡,所以采用
dotnet run 來執行這個專案時,你虽會看到 Http code 302 出現,它的意就是是
http redirect,也尽管是 SampleMiddleware 裡面所召开的 redirect 發生作用了.

  710官方网站从诱发灵感的中坚形式会,
暂时的按清闲状态是创造者转移注意、摆脱困境、产生灵感的一个生死攸关方法.如散步、沐浴、听音乐、阅读有以及所要化解的问题无关的书报、与正式以外的人数拉、入睡前还是正醒时的休养生息相当.据记载,
笛卡尔、高斯、彭加勒、爱因斯坦、华莱士、歌德、坎农、赫尔姆霍茨等丁还早已說有躺在铺上休养时得灵感的体验.日本扳平家创造力研究所於1983
年12 月~1984 年8 月, 对82 名日本发明家进行了统计, 结果表明,
有52%的口都在枕头上发了灵感, 乘车被发生灵感的产生45%,
步行中发出灵感的占46%,
而在劳作单位办公桌上起灵感的但占21%.由此可见,
在松弛状态下发生灵感的时, 要较在工作岗位上紧张劳作时多得多.当然,
上述情况只是灵感产生的形似景象, 具体灵感产生的历程中频繁因人而异,
并非千首一律.像,
法国物理学家皮埃皮·属里看于树丛中容易产生激情;费米喜欢躺在万籁俱寂的草坪上惦记问题;康川秀树习惯於夜间睡在床上考虑;法国数学家阿马达则常常于嘈杂中生灵感;剧作家贝克看有灵感的极其精美之随时是睡在浴盆中的时;而赫尔姆霍茨则以为是一大早要么天气睛朗登山时.还有人口以酒意拍下会带來灵感,
法国军乐家德利尔,
就是這样写下了老牌的"马赛曲";我国李白又有"斗酒诗百篇"的豪兴…….因此,
每个人应因自己之情形, 找有诱导灵感的极品办法跟极端机会,
从而更好地拓展创造.其实, 许多创造者已有意或无意地采取了這一点,
大发明家爱迪生就发出白天以于椅上打盹的习惯,
据說许多好之心劲便是這样产生的.

樂觀是一個颇不錯的旺盛,但盲目樂觀卻是骗局。

Middleware 的執行順序很重点

前解釋了 middleware 執行的過程,都是一個接著一個.不比之 middleware 對
HttpContext
的內容都或出例外之改變,因此執行的順序就顯得很重要.舉個例子,如果將上面
Configure() 的程式碼更動如下:

 1         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 2         {
 3             loggerFactory.AddConsole(Configuration.GetSection("Logging"));
 4             loggerFactory.AddDebug();
 5 
 6             app.UseSampleMiddleware();   // SampleMiddleware
 7 
 8             app.UseStaticFiles();        // StaticFiles
 9           
10             app.UseMvc(routes =>
11             {
12                 routes.MapRoute("default","{controller=Home}/{action=Index}/{id?}");
13             });
14         }

SampleMiddleware 跑至 StaticFiles 之前了,也便是当 SampleMiddleware
裡面做了 http redirect 到 NoName.html 將會失敗,為什麼會失敗呢 ? 因為
ApplicationBuilder 執行到 SampleMiddleware
時就如召开連線靜態網頁的功用,而這個功能是以产一個 middleware
(StaticFiles) 才會有的,因此 ApplicationBuilder 無法找到
NoName.html,所以于瀏覽器上即看不到 NoName.html 的內容.

Middleware 這樣的設計帶來很挺之方便及彈性,同時開發者自己吗如小心
middleware 前後相依性的問題.

 

你說呢?

Middleware 背後原理

由於現在 ASP.NET Core 已是 open source 了,所以最後來說明一下 middleware
原理的基本概念.整個 ASP.NET fundamental 的部份用了許多 function
delegate , task, denepdency injection 的撰寫手法,所以如果拘留 source code
之前,建議先對這三個東西先行了解才会對看 ASP.NET Core 的 source code
有幫助.

在眼前的程式碼中,你看来 RequestDelegate, 顧名思義就亮這是一個
delegate,它是故來代表 middleware 的 delegate. 它的 source code 在
https://github.com/aspnet/httpabstractions/blob/master/src/Microsoft.AspNet.Http.Abstractions/RequestDelegate.cs

IApplicationBuilder interface
是一個相當重要之介面,它定義了整個程式要为此到那些服務和參數,當然也富含要动用那些
middleware,它的 souce code 在
https://github.com/aspnet/httpabstractions/blob/master/src/Microsoft.AspNet.Http.Abstractions/IApplicationBuilder.cs,其中你可以看到
Use(),透過 Use() 的實作就可以把 middleware delegate 註冊到 host engine
上.

此外一個即使是 UseMiddlewareExtensions ,前面的程式範例曾就此了
builder.UseMiddleware(); 它會檢查你寫的 middleware
是匪是對的,比如来沒有 Invoke(),是未是单纯生一個 Invoke(),Invoke()
的參數有沒有一個凡是 HttpContext type,檢查都通過時便确立起該 middleware
instance 的 delegate.

故,當你的 ASP.NET Core 程式剛啟動時,在 Startup.cs 的 Configure()
會把拥有的 middleware delegate 建立起來,然後依序地停放內部的 stack
結構,以地方的範例來說, stack 結構裡第一個元素是 StaticFiles, 再來是
SampleMiddleware ,最後是 Mvc,接著每個 middleware 要被确立時是举行 stack
pop 的動作,所以 Mvc 的 _next 是 engine 裡一些內部的 middleware
處理器,然後 pop 出 SampleMiddleware 時,就将 SampleMiddleware 的 _next
指向前面一個 pop 出來的 Mvc, 依照這樣的邏輯一直到最好前头的
middleware.所以在 host engine 在 Build() 之前這些動作都會完成,然後
host engine 才会執行 Run().有關 host engine 可參考
https://github.com/aspnet/hosting/blob/master/src/Microsoft.AspNet.Hosting/WebHostBuilder.cs

每当寫這篇稿子時,ASP.NET Core RC2
還尚未上市,因此若您想試以上這些功能的話,Visual Studio
只能當成一個基本的程式碼編輯器了,restore, build 和 run 的動作還是要透過
DotNet CLI (https://github.com/dotnet/cli) 來完成.

初稿来自:https://dotblogs.com.tw/aspnetshare/2016/03/20/201603191-intromiddleware

总而言之, 虽然灵感的闪现是扑朔迷离、犹如幽灵、难以切实捉摸的,
但是灵感并无暧昧,
它吗是足以操纵的一模一样种植考虑活动.钱学森教授对准是举行了精辟之阐述:
"一点凡是早晚的, 人不告灵感, 灵感也不來, 得灵感的丁,
总是要透过同长段其他两种思维的苦苦追求來准备的.所以灵感还是人自己好开掘的大脑活动."

相关文章