0

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

[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 重新构建并再次运行该项目,我将获得正确的值。如果我有缓存问题,任何人都可以提出建议,除非重新运行项目,否则强制存储库具有相同的值?

谢谢

4

2 回答 2

0

我假设您使用实体框架并且一个存储库实例创建一个 EF 上下文。

操作过滤器可以重复用于多个请求,因此可以重复使用 EF 上下文。我们对一个实体的多个查询使用相同的 EF 上下文,该实体实际上被重用(类似于缓存)。

可能的解决方案:

  1. 更改合并选项
  2. 调用刷新()
  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)) 
            {
    ...
    

旁注:

  1. 使用NoTracking(MergeOption.NoTracking 或 AsNoTracking)提高性能见这里
  2. 这些解决方案并不相互排斥。您可以毫无问题地应用解决方案 3 和 4
于 2013-10-30T13:30:56.853 回答
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...
于 2013-10-29T11:17:10.463 回答