【问题标题】:ASP.NET MVC Global VariablesASP.NET MVC 全局变量
【发布时间】:2011-07-04 08:48:39
【问题描述】:

如何在 ASP.NET MVC 中声明全局变量?

【问题讨论】:

标签: c# .net asp.net asp.net-mvc global-variables


【解决方案1】:

从技术上讲,项目中任何位置的类上的任何静态变量或属性都将是全局变量,例如

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

但正如@SLaks 所说,如果处理不当,它们“可能”是不好的做法和危险的。例如,在上面的示例中,您将有多个请求(线程)尝试访问同一个属性,如果它是复杂类型或集合,这可能是一个问题,您必须实现某种形式的锁定。

【讨论】:

  • 我的赞成票。实际上,根据微软的说法,这是一种首选方式——由于性能原因,使用全局变量(静态)。 Application 对象用于与旧的 ASP 兼容。在此处阅读更多信息:link。如果考虑线程安全和并发性,AFAIK 静态和应用程序都需要锁,因为如果应用程序是线程安全的,那么您正在访问的数据可能不是。
  • 静态类不是会话安全的,即。在同一时刻,来自 2 个用户的 2 个同时请求将共享同一个变量,因此这会弄乱数据。为了用户会话安全,我认为必须像提到的 abatishchev 一样。
  • 我同意@Sunday,我认为这应该标记为正确答案,但是,最好的方法是实现线程安全的单例模式,例如:csharpindepth.com/Articles/General/Singleton.aspx
  • 这是最好的答案。
【解决方案2】:
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;
        }
    }
}

【讨论】:

  • 为什么使用Application类?应用程序对象用于与旧 ASP 兼容。此外,微软表示:“这提高了性能,因为您可以比访问应用程序字典中的项目更快地访问静态变量”。来源:link
  • @wishmesh:同意。另一方面 - 如果基于数据库的状态机打开,静态变量会被保存吗?
  • 你是对的。看来“静态变量法”在网园等场景中可能会失败。
  • @abatishchev 为什么你不在 Global.asax 中定义你的变量?,当你访问变量时,你对每个请求都进行了不寻常的类型转换。
  • @Gupta:本质上 HttpContext 和 Global.asax 都是遗留方法。一般来说,静态变量是一个更好的变量。但是每个都有优点和缺点,请参阅上面的评论。但是最终你不应该有共享变量,HTTP 是无状态的,所以你的代码应该是。
【解决方案3】:

您可以将它们放在应用程序中:

Application["GlobalVar"] = 1234;

它们仅在当前 IIS / 虚拟应用程序中是全局的。这意味着,在 webfarm 上,它们是服务器本地的,并且位于作为应用程序根目录的虚拟目录中。

【讨论】:

    【解决方案4】:

    对于非静态变量,我通过应用类字典整理如下:

    在 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);
    

    【讨论】:

    • 需要注意的是,你的回答的本质是“使用Application类字典。
    • @YasserZamani 这太完美了。但是如何修改Controller中的全局变量呢?每次我更改值时,它都会在其他请求中丢失。
    【解决方案5】:

    您还可以使用静态类,例如 Config 类或类似的东西...

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

    【讨论】:

      【解决方案6】:

      钢材远未热,但我将@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;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-15
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多