2010.9.8 蘇鵬
內容介紹
-Action的調用與屬性
預備知識
-安裝Visual Studio 2010 Express
-瞭解ASP.Net
-瞭解設計模式基本概念
喚起Action
Routing把Url拿到之後回到RouteTable去匹配Url,匹配完之後就能找到Controller和Action。
-ControllerActionInvoker
它能完成四個操作:
1.找到對應的Action
2.找到當前請求對應路由發過來的參數,匹配完之後傳給Action
3.調用Action方法所有的Filters(Filters是對Action的一種約束,只有經過Filters才知道Action是否真的可以執行)
4.調用ExecuteResult
Action匹配到Url
-從url中匹配Action名稱
Action和Route是不見面的,他們都通過前面的ControllerActionInvoker來通訊。
它首先要在Route中找到Dictionary類,並找到Action的key,這裡就能找到Action的名字。
Action選擇方法
預設情況通常使用反射的方式來找到Action的工作方法。這也是要求Action方法必須都是public的原因,如果不是public就拿不到名稱,也就沒法完成下面的工作。
方法標準:
-不允許有NonActionAttribute標記
-構架函數,屬性控制器,事件訪問器不能作為制定的action方法
-繼承自object的方法或者繼承自Controller的方法
這三種標準是由ActionSelectorAttribute來執行驗證的。
ActionNameAttribute
Action有一個命名規則,如果是一個Action方法命名為XXXCompleted,那這個方法一定要是非同步呼叫,如果是要同步調用的方法起這種名字,就必須得在Action上面加一個別名,叫ActionName。這樣ActionName匹配的時候不會匹配函數的名字,而會去匹配標記的名字。
ActionSelectorAttribute
- ActionSelectorAttribute定義
這個類的功能是驗證IsValidFromRequest作最後匹配,如果匹配內容是False,這個Action就會從list中消除,如果匹配為True,這個Action就會被驗證。最後我們的list會剩下一個匹配結果,這個函數就是最後被用來調用的。如果遍曆之後發現匹配結果多於1個,就會拋出一個異常。如果遍曆完之後發現一個Action都沒有匹配上,也會拋出一個異常。
AcceptVerbsAttribute
它是最簡單的一個Filters,它是混合了兩種Http請求的一個驗證方法。這就可以驗證請求是否符合針對的Action,這種方式也可以解決函數的重名問題。
類比Rest請求
HttpPostAttribute 對應建立模式
HttpPutAttribute 對應更新模式
HttpGetAttribute 對應讀模數式
HttpDeleteAttribute 對應刪除模式
有了這樣的對應,我們的CRUD(Create、Read、Update、Delete)就可以用一個Url完成了。這樣就進一步規範了Rest架構Web應用程式可用的一致性介面,並且對資源的操作取決於Http的方式。
映射參數
三種傳參方式:
1.RequestFormCollection
2.RouteData(推薦)
3.QueryString
一旦Action方法確定了之後,就需要映射Action的參數。
調用Action
-使用非同步Action
IIS在啟動的時候會有一個線程池,當使用者發起一個請求的時候,IIS從線程池中找出一個閒置線程,說你來響應這個請求吧,這個線程就會被設計為響應使用者的請求。比如使用者請求花了2秒時間完成,伺服器端就會在2秒內實現阻塞,等待請求的完成,這個線程既是響應使用者請求的線程,又是返回使用者結果的線程。線程執行完操作返回給使用者端之後,就回到線程池,因為它再次空閑了。預設情況下由於線程池的空閑線程比較多,這樣做沒什麼影響。但是如果請求特別多,IIS吃緊,IIS就沒法處理您的請求了,這時就會出現網路訪問繁忙的錯誤。
因此,我們有時候需要非同步方式來工作。當伺服器端拿到請求時,Action就喚醒一個線程,線程開啟工作。線程開啟工作之後就回到線程池了,工作就由後台其它的背景工作執行緒去做。工作結束之後MVC架構就會告訴IIS說我的工作運行完了,你再給我一個線程,我就可以把結果返回給你。這樣的方式使用者感覺沒有區別,但是伺服器的線程空閑比例會相對較高。
同步與非同步比較
使用同步方式
1.操作短小迅捷
非同步作業在返回結果的時候需要再次獲得線程,這個效能消耗也是要考慮的。
2.要求高可測試性
非同步情況Action在發送和返回的是不同線程,這在測試的時候很難實現,狀態沒法追蹤。
3.這個操作要求高CPU而不是高IO
使用非同步作業
1.通過測試發現該操作是網站應用程式效能瓶頸
這種阻塞瓶頸的解決方案,除了非同步Action,還有一種方法:OutputCahce,可以把Action的結果用OutputCahce緩衝。這種緩衝能有效縮短使用者的等待時間,把使用者發送的重複請求用緩衝結果返回,這樣可能資料不能及時保持最新,但是效果還是不錯的。而非同步請求對於使用者來說還是沒有區別的,使用者該等多久還是要等多久。
2.對並行性有高要求
3.對這個操作要求高IO而不是高CPU
IO操作是整個效能下降最容易產生問題的地方,因為IO訪問獨佔性,IO訪問本身是由作業系統轉寄的。
編寫非同步Action
同步訪問
非同步訪問
非同步訪問的Controller要繼承自AsyncController。Action名字的結尾也只能是Async和Completed,這兩個Action是一對,前者是響應Action請求,後者是返回資料給使用者。這兩者不能作為Action直接被調用。
在非同步模式下參數傳遞方式也不同,需要用AsynvManager.Parameters字典類儲存結果以便返回。因為同步是一個線程,而非同步是兩個線程,第一個線程結束之後,資料就沒有了,我必須使用一個中間變數在兩個線程之間傳遞資料,這個中間變數就是AsynvManager,它專門用來監視多變數的實現。
OutstandingOperation.Increment方法用來管理MVC當前的請求,這個操作非常重要,它主要是讓MVC架構知道當前有多少個操作處於掛起狀態,一旦把工作交給Action的後台以後,我們就不管了,OutstandingOperation每完成一個對應的Action,它就會-1,當它變成0的時候,我們就知道,這個Controller的工作已經完成了。對應的Completed方法就會被調用了。
並行操作的效能
同步訪問
非同步訪問
分析一下非同步操作。OutstandingOperation.Increment(3),說明現在又3個操作。每個操作一旦完成,就需要調用OutstandingOperation.Decrement把運算元-1。全部做完之後,有一個Completed函數,它去把當前所有資訊拿到,產生並返回。上面的三個操作都是並行的,因此執行的總時間是三個操作中最長的時間,而同步操作的執行總時間是三個操作的時間之和。這就是非同步訪問中的並行優勢,如果一個Action有多個內容,就應該用非同步並行來做。
對非同步請求使用標籤
非同步Action的標籤不能加在Completed方法之上。
逾時
AsyncTimeout預設情況45秒逾時。Timeout標籤可以更改逾時時間,NoAsync是永遠不逾時(不推薦)。如果直接指定在Controller上表示裡面每個Action都預設加了這個標籤。
關於非同步方法呼叫調用的附加說明
如果一定要用Completed尾碼的同步方法,需要使用別名
如果是Action方法是非同步,但是方法裡面的一些步驟需要同步,就可以用Begin和End成對的函數來做
需要注意的一點是,Html.Action和Html.RenderAction是可以指向非同步方法呼叫的,但是這個方法會以同步方式去調用。
更新Model層UpdateModel
這裡更新之前首先驗證ModelState是否可用,可用才更新,更新之後Redirect到Edit的Action。這裡選擇Redirect到其它地方,而不是直接返回一個View層的原因,是一個小技巧的時候。有時候使用者提交資料的時候,看見沒反應,就回去重新整理,重新整理便又會提交一條資料,當Post請求過來的時候,一旦完成它,就會跳到別的Edit,就可以編輯資料或者做一些別的相應的請求,而它每次重新整理的時候,會導致ModelState不可用,這個時候只把當前請求結果返回,避免使用者使用滑鼠重新整理頁面導致重複資料提交。
驗證資料
這個是寫在Model層的。
安全性
永遠不要不加處理的使用使用者的輸入(使用Html.Encode方式是很有必要的)
總結
-Action的調用與屬性
2010.10.1