2011-06-24 54 views
1

我們最近從mvc2升級到mvc3,並且我們的一個自定義授權過濾器(位於ActionResult方法)似乎只構造一次,但多次執行。我們知道這是因爲Filter包含錯誤列表(在構造函數中新建),並將錯誤添加到AuthorizeCore中。自定義授權過濾器中的MVC3會話過濾器奇怪行爲

定製過濾器是用來檢查用戶的訪問權限,以一個特定的操作方法(和他們的水平是存儲在Session)

一些代碼:

public class SecurityAttribute : AuthorizeAttribute 
    { 
     public int MinAccessLevel = 1; 
     public string UserRole = String.Empty; 
     private List<string> _errors; 

     public SecurityAttribute() 
     { 
      _errors = new List<string>(); 
     } 

     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 

      if (WebSession.AccessLevel < MinAccessLevel) 
       _errors.Add("Your access level(" + WebSession.AccessLevel + ") must be " + MinAccessLevel + " or higher"); 

      if (!String.IsNullOrEmpty(UserRole) && WebSession.UserRole != UserRole) 
       _errors.Add("Your User Role must be " + UserRole); 

      if (_errors.Any()) 
      { 
       var viewResult = new ViewResult() { ViewName = "SecurityError"}; 
       viewResult.ViewData.Model = new SecurityErrorViewModel(){Errors = _errors}; 
       filterContext.Result = viewResult; 
      } 
     } 
    } 

這將被用於像下面:

[HttpPost, Security(MinAccessLevel = 4)] 
public ActionResult Complete(int id, string userid){} 

在視圖(以隨機的間隔)輸出出現像這樣(在項目列表)

  • 你的訪問級別(6)必須是4或更高
  • 你的訪問級別(6)必須是4或更高
  • 你的訪問級別(6)必須是4或更高
  • 你的訪問級別( 6)必須是4或更高

這個問題只發生在我們升級到mvc3之後,所以我在尋找任何線索,爲什麼會發生這種情況,或者是否有適當的修復。我已經閱讀了有關無會話狀態控制器等各種SO職位,但這個似乎不符合我們所面臨

感謝情景,馬克

回答

2

由於按照MVC 3發佈說明:

在以前版本的ASP.NET MVC中,除少數情況外,每個請求都創建了操作過濾器。這種行爲從來不是一個有保證的行爲,而僅僅是一個實現細節,而過濾器的合同則認爲它們是無狀態的。在ASP.NET MVC 3中,過濾器被更積極地緩存。因此,任何不正確地存儲實例狀態的自定義操作過濾器都可能被破壞。

所以你不應該在操作過濾器中存儲錯誤。要麼直接在OnAuthorization方法中新建列表,要麼在其他地方需要訪問它們,您可以將它們存儲在HttpContext.Items或Session中。

+0

感謝以上 - 主要問題是我們有一個訪問級別,它看起來像從第一個請求(由某個用戶)緩存,然後任何一個有效訪問級別的人都有來自第一個請求的信息 – harrisonmeister

+0

對不起,我是一個duufus - 我明白你的意思,Errors變量在構造函數中被初始化並被緩存。當一個未經授權的用戶進入mvc3緩存時緩存了錯誤變量,我的_errors.Any()調用將總是返回它的第一個實例(至少包含一個錯誤!) – harrisonmeister

+0

這解釋得非常好http://bradwilson.typepad。 COM /博客/ 2010/07/ASPNET-MVC過濾器和 - statefulness.html – harrisonmeister