创建全局变量的最佳方法是什么?

时间:2015-07-01 19:25:57

标签: c# entity-framework asp.net-mvc-4

我有一个简单的问题,但它对我的项目非常重要:创建全局变量的最佳方法是什么?

在我的项目中,当用户进行身份验证时,我会根据他的个人资料构建所有Web菜单,例如声明或角色(我创建自己的声明),然后我开始构建菜单,其中包含特定页面用户有权访问。

在我的过滤方法中,如果用户有权访问菜单,我总是会检查数据库。

我想知道的是,是否有可能将这个菜单列表放在一个全局变量中,比如Session(" /)或Application,因为我不想去数据库检查这些权限,在这种情况下,如果我可以在服务器内存或类似的东西中获得此列表,那就更好了......

问候。

1 个答案:

答案 0 :(得分:0)

处理您的情况的最佳方法是采取儿童行动。您只需在项目的某个控制器中创建一个操作。由于这涉及用户级访问权限,因此我将使用AccountController

[AllowAnonymous]
[ChildActionOnly]
public ActionResult UserMenu()
{
    if (User.Identity.IsAuthenticated())
    {
        // logic to select your menu from database
        return View(menu);
    }

    // optionally you can return a different menu for anonymous users here
    return Content("");
}

然后,在UserMenu.cshtml目录中创建Views\Account视图。在此视图中,您只需使用您传入的模型实例(上面的menu)来呈现menu对象适用的网站导航的一部分。

最后,在您的布局中,无论您希望在何处显示此菜单,请致电:

@Html.Action("UserMenu", "Account");

如果你想只运行一次(真的更好地把它作为"偶尔"),那么你可以利用缓存。只需在子操作中添加以下附加属性:

[OutputCache(Duration = 3600, VaryByCustom = "User")]

没有内置的方法来改变特定用户的缓存,因此您必须创建自定义变体。但它相对容易。只需在Global.asax中添加如下内容:

public override string GetVaryByCustomString(HttpContext context, string arg) 
{ 
    if(arg.ToLower() == "user") 
    { 
        if (context.User.Identity.IsAuthenticated())
        {
            return context.User.Identity.Name;
        }

        return null;
    } 

    return base.GetVaryByCustomString(context, arg); 
}

然后,MVC将为每个唯一用户缓存UserMenu操作的输出1小时(3600秒),这意味着同一用户的任何其他请求都不会调用操作或向数据库发送任何查询直到缓存过期。