简体   繁体   English

使用ActionFilterAttribute时如何防止缓存

[英]How to prevent Caching , when using ActionFilterAttribute

I have created the following action filter class:- 我创建了以下动作过滤器类:

[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);
        }
    }

Which will call the following model repository class:- 它将调用以下模型存储库类:

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;

        }

The above will work fine, but if I change the database values then the repository values; 上面的方法可以正常工作,但是如果我更改数据库值,则可以更改存储库值。 isadminByuser & adminByGroup, Will have the same values (cached values). isadminByuser和adminByGroup,将具有相同的值(缓存的值)。 but if I stop the project and re-build and run the project again from visual studio I will get the right values. 但是,如果我停止该项目并重新构建并从Visual Studio重新运行该项目,我将获得正确的价值。 So can anyone advice if I am have a caching problem , which is forcing the repository to have the same values unless re-run the project? 因此,如果我有一个缓存问题,除非重新运行项目,否则这将迫使存储库具有相同的值,那么有人可以提出建议吗?

Thanks 谢谢

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...

I assume that you use Entity Framework and one repository instance creates one EF context. 我假设您使用实体框架,并且一个存储库实例创建一个EF上下文。

Action filters can be reused for multiple requests so the EF context is reused. 动作过滤器可以重用于多个请求,因此EF上下文可以重用。 We you use the same EF context for multiple queries to an entity, the entity is actually reused (something like a cache). 我们对同一实体的多个查询使用相同的EF上下文,该实体实际上已被重用(类似于缓存)。

Possible solutions: 可能的解决方案:

  1. Change the MergeOption 更改MergeOption
  2. call Refresh() 调用Refresh()
  3. use AsNoTracking() 使用AsNoTracking()
  4. Preferred solution Do not reuse the context so that you get the latest data and your context doesn't keep more and more entities in memory. 首选解决方案不要重复使用上下文,这样您就可以获取最新数据,并且上下文不会在内存中保留越来越多的实体。

     [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)) { ... 

Side notes: 旁注:

  1. using NoTracking (MergeOption.NoTracking or AsNoTracking) increases performance See here 使用NoTracking (MergeOption.NoTracking或AsNoTracking)可以提高性能, 请参见此处
  2. The solutions are not mutually exclusive. 解决方案不是互斥的。 You can apply solution 3 and 4 without any problem 您可以毫无问题地应用解决方案3和4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM