使用ActionFilterAttribute时如何防止缓存

时间:2013-10-28 22:26:22

标签: c# asp.net asp.net-mvc caching

我创建了以下动作过滤器类: -

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {
        Repository repository = new Repository();
        public string Model { get; set; }
        public string Action { get; set; }

public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string ADusername = filterContext.HttpContext.User.Identity.Name.Substring(filterContext.HttpContext.User.Identity.Name.IndexOf("\\") + 1);
            if (!repository.can(ADusername,Model,Action)) 
            {
filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");

            }

base.OnActionExecuting(filterContext);
        }
    }

将调用以下模型存储库类: -

public bool can(string user, string Model, string Action) {
if (Model == "Admin")
            {
bool isadminByuser =  tms.SecurityRoles.Where(a => a.Name == "Administrator").SingleOrDefault().SecurityRoleUsers.Any(a => a.UserName.ToLower() == user.ToLower());
var adminByGroup = tms.SecurityRoles.Where(a => a.Name == "Administrator").SingleOrDefault().Groups.Select(a2 => a2.TMSUserGroups.Where(a3 => a3.UserName.ToLower() == user.ToLower()));
bool isadminByGroup = adminByGroup.Count() >= 1;
if (isadminByGroup || isadminByuser) 
{

                    return true;
                }
            }
            return false;

        }

以上工作正常,但如果我更改数据库值,那么存储库值; isadminByuser& adminByGroup,将具有相同的值(缓存值)。但如果我停止项目并从visual studio重新构建并运行项目,我将得到正确的值。如果我遇到缓存问题,那么任何人都可以建议,除非重新运行项目,否则会强制存储库具有相同的值?

谢谢

2 个答案:

答案 0 :(得分:0)

You can use like this..

[NoCache]
public ActionResult Ex()
{
    //enter code here
}

or

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")] 
public ActionResult Ex()
{
   //enter code here
}

Hope it helps...

答案 1 :(得分:0)

我假设你使用Entity Framework,一个存储库实例创建一个EF上下文。

可以为多个请求重用动作过滤器,以便重用EF上下文。我们使用相同的EF上下文对实体进行多次查询,实际上实体被重用(类似于缓存)。

可能的解决方案:

  1. 更改MergeOption
  2. 致电Refresh()
  3. 使用AsNoTracking()
  4. 首选解决方案不要重复使用上下文,以便获取最新数据,并且您的上下文不会在内存中保留越来越多的实体。

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {            
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            Repository repository = new Repository(); //create the repository here
            if (!repository.can(ADusername,Model,Action)) 
            {
    ...
    
  5. 附注:

    1. 使用 NoTracking (MergeOption.NoTracking或AsNoTracking)提高效果See here
    2. 解决方案并非相互排斥。您可以毫无问题地应用解决方案3和4