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

问题描述:

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

在我的项目中,当用户通过身份验证时,我会根据他的个人资料构建所有Web菜单,比如声明或角色(我创建了自己的声明),然后我开始构建菜单,用户有权访问。

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

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

问候。

+13

创建全局变量的最佳方式不是创建一个。 –

+2

应避免使用全局变量。您可以使用具有您调用的方法的服务类来获取此信息。该服务方法会触发数据库或执行所需的设置,并将结果缓存到私有静态集合中。你应该真的避免一个真正全球化的公共静态属性。它会在以后咬你。 –

+1

您应该检查用户的角色。如果用户遇到特定角色,然后显示菜单?为什么你不想要这种方法? –

最好的方式来处理你的情况是与孩子的行动。你只需创建一个动作在你的项目中的一些控制器中,因为这涉及用户级访问,所以我将使用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(""); 
} 

然后,您在Views\Account目录中创建UserMenu.cshtml视图。在这个视图中,您只需使用您传入的模型实例(上面的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秒),由同一个用户意味着任何其他请求都将在缓存过期之前,不要调用该操作或向数据库发送任何查询。

+0

完美!这正是我想要的!我有两个简单的问题:1)如果你知道我的意思,这个'OutputCache'对于应用程序来说是一件好事,或者是一件'坏事'。2)在'GetVaryByCustomString'方法中,有什么区别'return null'和'return context.User.Identity.Name'之间?因为这两者对执行'ChildAction'没有任何影响...... –