2016年6月14日 星期二

[ASP.NET MVC]驗證屬性(AuthorizeAttribute)的生命週期

近期在開發MVC網站時,使用Filter AuthorizeAttribute來做登入以及權限驗證,而其執行的生命週期預想會類似於MVC Controller的狀況,但實際上卻不是如此?!以下請來看看整件事情的原委吧。

會特別去研究這個驗證屬性的生命週期是因為我自己擴充了該屬性來驗證關於權限設定的部分,此部分會依據資料庫設定的資料來決定該使用者是否擁有該Controller Action的權限。而與資料庫的連線是當驗證物件實體化後同時與資料庫建立連線,依照當時設計所對於MVC生命週期的了解,每一個Request會實體化一個新的Controller,也同時實體化一個新的Filter物件來做驗證。

但有趣的是這樣的設計等於每個Request都會去跟資料庫建立連線,在同時或是短時間內多個Request發出後,Entity framework卻發生了這樣的錯誤訊息:
基礎提供者在 Open 失敗、基礎提供者在 ConnectionString 失敗。
但...我很確定連線字串是沒有問題的,而是在執行一段時間後才跳出錯誤。

基於這樣的故事背景,不得不懷疑我當初的預想是不是有問題,在經過一番折騰後有了重大發現!!

的確每個新的Controller Request會實體化一個新的Controller,但是驗證屬性卻不是!!驗證屬性與Controller是一個pair,一個Controller會有一個對應的驗證屬性實體,當第一次Controller實體化時也同時會建立一個驗證屬性實體,當Request到Response結束後Controller的生命週期就結束了,但是驗證屬性仍然存在!!

所以當下一次新的請求發生時,仍然會建立一個新的Controller實體,而驗證屬性只有在第一次新的Controller Request才會實體化,之後的Request都會找對應的驗證實體來執行驗證。

結論就是終於搞清楚驗證屬性的生命週期了,這樣在程式開發到除錯等等也更能夠對症下藥了!!改Code去~


沒有留言:

張貼留言