2015-07-01 97 views
0

我有一個簡單的問題,但它對我的項目非常重要:創建全局變量的最佳方法是什麼?什麼是創建全局變量的最佳方式?

在我的項目中,當用戶通過身份驗證時,我會根據他的個人資料構建所有Web菜單,比如聲明或角色(我創建了自己的聲明),然後我開始構建菜單,用戶有權訪問。

在我的過濾方法中,如果用戶有權訪問菜單,我總是檢查數據庫。

我想知道的是,如果有可能將這個菜單列表放在一個全局變量中,如Session(「/」或Application),因爲我不想去數據庫檢查這些權限,在這種情況下是更好,如果我能得到這個名單在服務器內存或類似的東西...

問候。

+13

創建全局變量的最佳方式不是創建一個。 –

+2

應避免使用全局變量。您可以使用具有您調用的方法的服務類來獲取此信息。該服務方法會觸發數據庫或執行所需的設置,並將結果緩存到私有靜態集合中。你應該真的避免一個真正全球化的公共靜態屬性。它會在以後咬你。 –

+1

您應該檢查用戶的角色。如果用戶遇到特定角色,然後顯示菜單?爲什麼你不想要這種方法? –

回答

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(""); 
} 

然後,您在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'沒有任何影響...... –

相關問題