2012-10-19 42 views
0

我一直在使用基於授權屬性的MvcSiteMapProvider,直到我們引入了一個從AuthorizeAttribute派生出來的新類,它才行。主要的區別在於它的構造函數簽名:將參數添加到AuthorizeAttribute構造函數會導致MvcSiteMapProvider失敗?

public MyAuthorizeAttribute(param RoleCode[] roles) { 
    Roles = string.join(",", roles.Select(r => r.ToString()); 
} 

而且...... MvcSiteMapProvider出意想不到的結果:只有MyAuthorizeAttribute標記的行動也變得不可見。我已經通過禁用這個構造函數來檢查 - 一切都像在向構造函數中添加參數之前一樣。另外 - 它不是params具體 - 任何參數(事件int)導致這種行爲。

正如我從MvcSiteMapProvider來源所瞭解的,它發出了一些代碼來模擬授權屬性 - 但看起來像是不可能保存由外部代碼生成的程序集。我知道有一個解決方法 - 使用某種可枚舉的屬性,但你有任何建議如何使它與構造參數一起工作?你知道爲什麼MvcSiteMapProvider的行爲如此嗎?

回答

0

所以,花了一些時間在調試後,我意識到了答案:動態代理

問題是,在MVC框架內的請求執行過程中,沒有簡單的方法可以找出從AuthorizeAttribute派生的類如何執行其工作。在訪問檢查失敗的情況下,有些可能會拋出異常,一些 - 返回401狀態碼,一些重定向到登錄頁面,等等。

但MvcSiteMapProvides這樣做!它採用以下解決方法:

  • 如果類是AuthorizeAttribute
    • 創建InternalAuthorize類,這是相當簡單的一個實例。
    • 複製那裏的所有屬性和
    • 調用AuthorizeCore返回布爾值的方法。
  • 其他
    • 生成一個類型屬性的派生的代理類,
    • 創建實例,/// < <在這裏我們得到一個異常
    • 副本都在那裏和
    • 性質
    • 調用AuthorizeCore返回布爾值的方法。

因爲很顯然,這不是一件容易的事做代理,這是瞭解你的構造函數的參數。當然會引發關於缺省構造函數缺失的例外情況,但它會被空的catch子句使用。這真是令人傷心 - 至少有一個調試跟蹤會爲我節省幾個小時。

因此,答案在最後:

  • 顯然,你應該使用無參數的構造函數屬性(爲什麼啊,爲什麼這不是在任何地方提到?)
  • 創建自定義acl提供程序:實現IAclModule接口並釋放有關您自己的授權屬性的知識。
相關問題