2010.9.9 蘇鵬
內容介紹
-基本Filter的使用
-自訂開發Filter
預備知識
-安裝Visual Studio 2010 Express
-瞭解ASP.Net
-瞭解設計模式基本概念
Filter的作用
-對Action的附加說明
ASP.Net MVC中的Filter
-Authorize
ASP.Net裡面也有授權管理,它是用Membership來做的,綁定每個檔案的Url。這裡MVC的授權是在Action訪問之前要求使用者名稱和密碼,證明您是具有相應操作許可權的
-HandleError
Action中會拋出異常,HandleError加上之後就能處理這個異常
-OutputCache
緩衝輸出的內容
-RequireHttps
這也是授權,但是要求更嚴格,網路上傳輸的請求很多都是Http,即超文字傳輸通訊協定 (HTTP),它傳輸的文本是明文的,它頂多做點Encode是把一些字元轉義一下,不會對資料進行加密,這樣是很不安全的。現在網路的Sniffer技術已經很流行了,任何人只要在橋接器上架一個監聽器,都能聽到你相應的流量。如果對流量進行分析,就能看到流量裡的內容。所以對於一些高安全性要求的網路,例如網路銀行等,都是用Https進行傳輸,s的意思是傳輸在SSL層上,SSL層是傳輸的一個加密協議,它保證傳輸過程當中,雙方使用一種保密機制來進行傳輸,而不會被第三方監聽到,即使監聽到也分析不明白,全部是亂碼。所以Https有效地避免了傳輸資料被監聽的情況。RequireHttps標籤,它就會要求你,一旦使用這個標籤,資料轉送一定必須得是Https進行的。如果是Http的,那就會有一些處理策略。
Authorize
-AuthorizeAttribute標籤
在ASP.Net 2.0時代,我們為了讓使用者使用角色和許可權管理,微軟提供了一套針對使用者角色和許可權管理的架構,即Membership。這個核心部分有幾部分,第一部分有一大堆Membership對應的控制項,這些控制項能協助您建立使用者、登入、顯示使用者登入狀態等等。第二部分有一堆Service的API,隸屬於Membership命名空間下,它能建立使用者、查看使用者是否登入、驗證使用者是否屬於某一許可權。最底層,它有一個資料庫,裡面有5個表,其中有角色Roles(每一不同角色針對不同檔案夾訪問)、使用者Users(每個Users隸屬於一個角色,Users有登入資訊),這5個表儲存了許可權管理的資料。這個Service依然在今天MVC架構中可以使用。這就是今天的AuthorizeAttribute標籤。標籤中的Roles就是驗證登陸的角色名稱,這個例子表名只有角色名稱叫Admins和SuperAdmins的使用者可以訪問。如果是使用者名稱驗證,可以寫Users="XXX,XXX"(用逗號分隔)。只有指定的名稱的屬性才能訪問到。
這和以前ASP.Net WebForm的Membership用法有所不同。假如有一些頁面是只有Admin使用者能操作的,那我們就建立一個叫Admin的檔案夾,接下來把使用者操作檔案全部放到Admin檔案夾下面。使用者想要訪問這些檔案的時候,就必須要通過許可權認定。對每一檔案夾的定義Rules寫在Webconfig裡邊。
MVC架構下就無法複用這種策略,為什麼呢?想想MVC架構的基礎概念。每一個請求現在對應的已經不再是
一個檔案了,它對應的是個Action。這就使得我們指定一個檔案夾下的檔案的方式不合適了。所以針對不同使用者,我們要限制和管理的只不過是他們的一個操作。這個操作最小粒度就是一個函數,即Action。這樣把許可權和使用者操作掛鈎,而不是檔案,反而更有效。
上面的例子中,如果要使用DeleteAllUsers方法,必須首先具有Admins或SuoerAdmins的角色,通過AdminController的許可權,然後還需要是名叫Phil的使用者,才能訪問這個Action。這個邏輯關係實際上是一種疊加的邏輯關係。
如果唯寫了Authorize的標籤,沒有寫後面的條件,那就說明這隻是登入授權,只要使用者登入就可以訪問Action。如果是沒登陸想訪問帶有Authorize標籤的方法,會返回一個401錯誤,它在IIS裡面的意思就是您所訪問的資源未經授權。當然,同ASP.Net WebForm一樣,MVC架構中這種未授權的情況也可以讓使用者跳轉到一個登陸頁面。
RequireHttps
這個標籤要求請求必須是Https。它既可以放在Controller上,也可以放在Action上。RequireHttps標籤的Action被訪問的時候,要求必須使用SSL來進行解析,如果有一個不是使用SSL的請求發過來的時候,就要分情況討論了,如果是Get請求,那麼我們自動會把協議變成Https的,然後接著訪問。但要注意,您的Web伺服器還必須得支援Https,如果它把協議變成了Https,但是您的伺服器不支援Https,那一樣是報告404錯誤的。如果是Post請求,那麼是沒法加密Post裡面的資訊的,因此會拋出異常。
OutputCache
-CacheProfile
指定Cache名字,這個名字可以寫在Filter上,也可以寫在Web.config上。寫在Web.config上就可以複用OutputCache的規則
-Duration
指定緩衝釋放時間,單位秒
-Location
預設情況是Any
-NoStore
表示不緩衝結果
-SqlDependency
指定緩衝是根據某一SQL Server指定的某一表的值來緩衝的,當值改變的時候緩衝釋放,當值沒變的時候一直緩衝
-VaryByContentEncoding
它是用一個逗號分隔的字串說明緩衝所用的編碼格式
-VaryByCustom
是否緩衝取決於調用GetValueByCustomString這個函數。這個函數是在Global.asax.cs裡的,你在這裡重載它的GetValueByCustomString函數,就能自己定製緩衝
-VaryHeader
它是取決於Http請求的資訊做緩衝釋放,你可以使用不同的方式來請求同一個Action來實現緩衝的釋放
-VaryByParam
根據參數釋放緩衝
在Action上寫OutputCache標記之後,當請求發到Controller,Controller執行ActionInvoker找到Action的時候,說:你,準備起來幹活了!Action說我不用幹啊,你看我這有OutputCache標記呢,釋放時間還沒到呢,你去View層直接把緩衝結果放回去就完事。這樣就避免了效能的額外開銷。
OutputCache在Web.config裡面的配置
Exception Filter
它是指定一個Action去處理你的異常,並且指定一個View視圖來指定顯示你的異常。
如果是沒有Handle異常,那麼就不能正確的通過視圖返回結果給使用者,就會發生很多奇怪的事情,例如一運行就會報錯,而錯誤出處和資訊都不知道。
需要注意的是,異常捕獲的定義需要從小到大地寫,你要細分地每一個都寫出來。它們的調用順序是Order1先調用,Order2後調用。如果不寫Order調用的順序是未知的,不是誰寫在上面誰先調用。應該盡量把大的異常的Order寫的靠後。
在預設Debug運行下Filter不會捕獲這個異常。因為Debug模式如果有異常直接拋給編譯器了,這個標籤就不起作用。
Custom Filters
要寫自訂Filter,首先要繼承自FilterAttribute類,然後要實現上面4個介面中的一個。其中ActionFilter和ResultFilter最常用,一個是專門在Action執行前執行中做操作的,一個是執行後返回前做操作的。
ActionFilterAttribute
ActionExecutingContext
它有兩個參數:
-ActionParameters
它是一個字典類,它主要用來傳遞給Action的參數
-Result
在當前請求被取消的時候,Filter會自己產生一個ActionResult來代替從Action傳過來的結果,把它傳給使用者
ActionExecutedContext
它有四個屬性:
-Canceled
它是布爾值,如果設為True,Action請求就被取消,直接就會構造一個Result,給ActionExecutedContext裡的Result,直接返回。
-Exception
它是拋出異常的支援情況
-ExceptionHandled
它是一個布爾值,可以把它設為True來撤銷已經返回的Result。一旦它設為True,拋出異常,所有的Action都拿不到這個ActionResult結果,這個Result就永遠丟失了
-Result
Action的返回結果
ResultExecutingContext
-Cancel
-Result
ResultExecutedContext
-Canceled
-Exception
-ExceptionHandled
-Result
編寫ActionFilter
這裡StopWatch之所以用ViewData存放而不是用全域的變數存放,是因為全域變數會對效能有一定影響。還不如把資料交給Action,因為反正Controller都會把資料給Action。
Filter執行順序
-1.Order小的先執行
-2.具有同樣Order的,看定義範圍
-3.無Order的最後執行
-4.代碼內部定義的(自己定義的Filter)優先執行
-5.同類型的Filter無法確定執行順序
總結
-基本Filter的使用
-自訂開發Filter
2010.10.2