我们最近从mvc2升级到mvc3,我们的一个自定义授权过滤器(位于ActionResult方法上)似乎构造了一次,但执行了多次。我们知道这一点,因为Filter包含一个错误列表(在构造函数中新建),并且错误被添加到AuthorizeCore上。
自定义过滤器用于检查用户对特定操作方法的访问权限(其级别存储在会话中)
一些代码:
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){}
视图上的输出(以随机间隔)如此显示(在项目符号列表中)
这个问题只在我们升级到mvc3后才会发生,所以我正在寻找有关为什么会发生这种情况或适当修复的任何线索。我已经阅读了关于无会话状态控制器等的各种SO帖子,但这似乎不符合我们面临的情况
谢谢,Mark
答案 0 :(得分:2)
根据MVC 3发行说明:
在以前版本的ASP.NET MVC中,除少数情况外,基于每个请求创建了动作过滤器。这种行为从来都不是保证行为,而只是一个实现细节,而过滤器的合同是将它们视为无状态。在ASP.NET MVC 3中,过滤器被更积极地缓存。因此,任何不正确地存储实例状态的自定义操作过滤器都可能会被破坏。
因此,您不应将错误存储在操作过滤器中。要么直接在OnAuthorization
方法中新建列表,要么在其他地方需要访问它们,您可以将它们存储在HttpContext.Items或Session中。