80

How do you declare global variables in ASP.NET MVC?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Beginner
  • 28,539
  • 63
  • 155
  • 235
  • 1
    Your answer is - [MVC - How to declare global variables ](http://stackoverflow.com/questions/4171089/how-to-define-a-global-variable-in-asp-net-web-app) - [Global variables in ASP.NET MVC](http://stackoverflow.com/questions/2974542/how-to-declare-a-global-variable-at-an-aspx-page) – Saurabh Gokhale Feb 25 '11 at 14:53
  • @SLaks It's very usefull when you want to create a quick and dirty prototype for a client. Poor designs and bad practices don't matter at all when you are making throw-away presale UI demo. – romanoza Mar 13 '16 at 08:46

6 Answers6

81

Technically any static variable or Property on a class, anywhere in your project, will be a Global variable e.g.

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

But as @SLaks says, they can 'potentially' be bad practice and dangerous, if not handled correctly. For instance, in that above example, you would have multiple requests (threads) trying to access the same Property, which could be an issue if it was a complex type or a collection, you would have to implement some form of locking.

Sunday Ironfoot
  • 12,840
  • 15
  • 75
  • 91
  • 9
    My upvote. Actually, according to Microsoft, this is a preferred way - to use Global variables (static) because of performance. And Application object is used for compatibility with old ASP. Read more here: [link](http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607). AFAIK both static and Application requires locks if think about thread safety and concurrency, because if Application is thread-safe, the data you are accessing may be not. – Maris B. May 03 '12 at 08:34
  • The static classes are not session safe, ie. in the same moment 2 simultaneous requests from 2 users will share the same variable, so this will mess up the data. To be user session safe I think must be something like abatishchev mentioned. – Vasil Popov Oct 24 '12 at 10:59
  • 1
    I agree with @Sunday and I think this one should mark as correct answer, however, the best way to do it is to implement a thread-safe singleton pattern, like: http://csharpindepth.com/Articles/General/Singleton.aspx – Tohid Dec 27 '12 at 19:35
  • That is the best answer. – Matheus Miranda May 31 '17 at 00:41
52
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;
        }
    }
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • Why use Application class? Application object is used for compatibility with older ASP. Also, Microsoft says: "This increases performance because you can access a static variable faster than you can access an item in the Application dictionary". Source: [link](http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607) – Maris B. May 03 '12 at 08:38
  • @wishmesh: Agree. On other hand - will static variables be saved if database-based state machine is turned on? – abatishchev May 03 '12 at 08:57
  • 1
    You are correct. It seems that "static variable approach" may fail in web garden and other scenarios. – Maris B. Jul 17 '12 at 09:00
  • @abatishchev Why you not define your variable in Global.asax?, You are doing unusual typecasting on every request when you access the variable. – Anirudha Gupta Mar 31 '16 at 11:51
  • @Gupta: essentially both HttpContext and Global.asax are legacy approaches. Static variables is a better one, in general. But each has pros and cons, see the comment above. However ultimately you should have no shared variables, HTTP is stateless so should be your code. – abatishchev Mar 31 '16 at 16:37
24

You can put them in the Application:

Application["GlobalVar"] = 1234;

They are only global within the current IIS / Virtual applicition. This means, on a webfarm they are local to the server, and within the virtual directory that is the root of the application.

GvS
  • 52,015
  • 16
  • 101
  • 139
18

For non-static variables, I sorted it out via Application class dictionary as below:

At 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);
        }
    }
}

And in Controller:

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

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

    }
}

In this way we can have global variables in ASP.NET MVC :)

NOTE: If your object is not string simply write:

return View(HttpContext.Application["X"] as yourType);
Yasser Zamani
  • 2,380
  • 21
  • 18
  • 2
    It should be noted that the essennce of your answer is "use the `Application` class dictionary. – Andrew Barber May 21 '12 at 08:23
  • @YasserZamani that's perfect. but how to modify the global variables in Controller? every time i changed the value, it lost in other requests. – Sheldon Wei Aug 18 '14 at 06:43
8

You could also use a static class, such as a Config class or something along those lines...

public static class Config
{
    public static readonly string SomeValue = "blah";
}
Ian P
  • 12,840
  • 6
  • 48
  • 70
0

The steel is far from hot, but I combined @abatishchev's solution with the answer from this post and got to this result. Hope it's useful:

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;
        }
    }
}
paulo.vin
  • 104
  • 3