2011-02-25 97 views
59

如何在ASP.NET MVC中聲明全局變量?ASP.NET MVC全局變量

+1

你的答案是 - [MVC - 如何聲明全局變量(http://stackoverflow.com/questions/4171089/how-to-define-a-global-variable-in- asp.net的網絡應用程序) - [全局變量在ASP.NET MVC](http://stackoverflow.com/questions/2974542/how-to-declare-a-global-variable-at-an-aspx-page ) – 2011-02-25 14:53:23

+0

@SLaks當你想爲客戶創建一個快速和髒的原型時,它非常有用。糟糕的設計和糟糕的做法根本無關緊要,因爲你正在製作不需要的預售UI演示。 – romanoza 2016-03-13 08:46:25

回答

41
public static class GlobalVariables 
{ 
    // readonly variable 
    public static string Foo 
    { 
     get 
     { 
      return "foo"; 
     } 
    } 

    // read-write variable 
    public static string Bar 
    { 
     get 
     { 
      return HttpContext.Current.Application["Bar"] as string; 
     } 
     set 
     { 
      HttpContext.Current.Application["Bar"] = value; 
     } 
    } 
} 
+0

爲什麼使用Application類?應用程序對象用於與較舊的ASP兼容。此外,微軟表示:「這會提高性能,因爲您可以比訪問應用程序字典中的項目更快地訪問靜態變量。」資料來源:[鏈接](http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607) – 2012-05-03 08:38:08

+0

@wishmesh:同意。另一方面 - 如果基於數據庫的狀態機打開,靜態變量會保存嗎? – abatishchev 2012-05-03 08:57:25

+1

你是對的。看起來,「靜態變量方法」在網絡園區和其他場景中可能會失敗。 – 2012-07-17 09:00:41

23

你可以把它們放在應用:

Application["GlobalVar"] = 1234; 

他們只是當前IIS /虛擬applicition內全球。這意味着,在一個webfarm上它們是服務器本地的,並且在作爲應用程序根目錄的虛擬目錄中。

7

你也可以使用一個靜態類,如配置類或類似的規定?

public static class Config 
{ 
    public static readonly string SomeValue = "blah"; 
} 
75

技術上任何靜態變量或屬性的一類,在項目中的任何地方,將是一個全局變量,例如

public static class MyGlobalVariables 
{ 
    public static string MyGlobalString { get; set; } 
} 

但作爲@SLaks說,他們可以「潛在」是不好的做法和危險,如果不能正確處理。例如,在上面的例子中,你會有多個請求(線程)試圖訪問相同的屬性,如果它是一個複雜類型或集合可能是一個問題,你將不得不實現某種形式的鎖定。

+8

我的upvote。實際上,根據微軟的說法,這是一個首選的方法 - 由於性能使用全局變量(靜態)。並且Application對象用於與舊的ASP兼容。閱讀更多此處:[鏈接](http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607)。如果考慮線程安全性和併發性,AFAIK static和Application需要鎖,因爲如果Application是線程安全的,那麼您訪問的數據可能不是。 – 2012-05-03 08:34:35

+0

靜態類不是會話安全的,即。在同一時刻,來自2個用戶的2個同時請求將共享相同的變量,因此這會弄亂數據。要成爲用戶會話安全,我認爲必須像提到的abatishchev一樣。 – 2012-10-24 10:59:50

+0

我同意@Sunday,我認爲這應該標記爲正確的答案,但是,最好的方法是實現線程安全的單例模式,如:http://csharpindepth.com/Articles/General/Singleton .aspx – Tohid 2012-12-27 19:35:52

18

對於非靜態變量,我整理出來通過應用如下類字典

在Global.asax.ac:

namespace MvcWebApplication 
{ 
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801 

    public class MvcApplication : System.Web.HttpApplication 
    { 
     private string _licensefile; // the global private variable 

     internal string LicenseFile // the global controlled variable 
     { 
      get 
      { 
       if (String.IsNullOrEmpty(_licensefile)) 
       { 
        string tempMylFile = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(typeof(LDLL.License)).Location), "License.l"); 
        if (!File.Exists(tempMylFile)) 
         File.Copy(Server.MapPath("~/Content/license/License.l"), 
          tempMylFile, 
          true); 
        _licensefile = tempMylFile; 
       } 
       return _licensefile; 
      } 
     } 
     protected void Application_Start() 
     { 
      Application["LicenseFile"] = LicenseFile;// the global variable's bed 

      AreaRegistration.RegisterAllAreas(); 

      RegisterGlobalFilters(GlobalFilters.Filters); 
      RegisterRoutes(RouteTable.Routes); 
     } 
    } 
} 

並在控制器:

namespace MvcWebApplication.Controllers 
{ 
    public class HomeController : Controller 
    { 
     // 
     // GET: /Home/ 

     public ActionResult Index() 
     { 
      return View(HttpContext.Application["LicenseFile"] as string); 
     } 

    } 
} 

通過這種方式,我們可以在ASP.NET MVC中擁有全局變量:)

注意:如果你的對象是不是字符串乾脆寫:

return View(HttpContext.Application["X"] as yourType); 
+2

應該注意的是,你的答案的重要性是「使用'Application'類字典 – 2012-05-21 08:23:02

+0

非常感謝@AndrewBarber,我更新了我的答案! – 2012-05-21 08:27:53

+0

@YasserZamani這是完美的,但如何修改Controller中的全局變量?當我改變了價值,它在其他請求中丟失了。 – 2014-08-18 06:43:48

0

鋼是遠離熱,但我結合@ abatishchev與來自this post答案的解決方案,得到了這個結果。希望這是有用的:

public static class GlobalVars 
{ 
    private const string GlobalKey = "AllMyVars"; 

    static GlobalVars() 
    { 
     Hashtable table = HttpContext.Current.Application[GlobalKey] as Hashtable; 

     if (table == null) 
     { 
      table = new Hashtable(); 
      HttpContext.Current.Application[GlobalKey] = table; 
     } 
    } 

    public static Hashtable Vars 
    { 
     get { return HttpContext.Current.Application[GlobalKey] as Hashtable; } 
    } 

    public static IEnumerable<SomeClass> SomeCollection 
    { 
     get { return GetVar("SomeCollection") as IEnumerable<SomeClass>; } 
     set { WriteVar("SomeCollection", value); } 
    } 

    internal static DateTime SomeDate 
    { 
     get { return (DateTime)GetVar("SomeDate"); } 
     set { WriteVar("SomeDate", value); } 
    } 

    private static object GetVar(string varName) 
    { 
     if (Vars.ContainsKey(varName)) 
     { 
      return Vars[varName]; 
     } 

     return null; 
    } 

    private static void WriteVar(string varName, object value) 
    { 
     if (value == null) 
     { 
      if (Vars.ContainsKey(varName)) 
      { 
       Vars.Remove(varName); 
      } 
      return; 
     } 

     if (Vars[varName] == null) 
     { 
      Vars.Add(varName, value); 
     } 
     else 
     { 
      Vars[varName] = value; 
     } 
    } 
}