Globale ASP.NET MVC-Variablen

73

Wie deklarieren Sie globale Variablen in ASP.NET MVC?

Anfänger
quelle
1
Ihre Antwort lautet - [MVC - Deklarieren globaler Variablen] ( stackoverflow.com/questions/4171089/… ) - Globale Variablen in ASP.NET MVC
sgokhales
@SLaks Es ist sehr nützlich, wenn Sie einen schnellen und schmutzigen Prototyp für einen Kunden erstellen möchten. Schlechte Designs und schlechte Praktiken spielen überhaupt keine Rolle, wenn Sie eine wegwerfbare Vorverkaufs-UI-Demo erstellen.
Romanoza

Antworten:

49
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
quelle
Warum Anwendungsklasse verwenden? Das Anwendungsobjekt wird aus Gründen der Kompatibilität mit älteren ASP verwendet. Außerdem sagt Microsoft: "Dies erhöht die Leistung, da Sie schneller auf eine statische Variable zugreifen können als auf ein Element im Anwendungswörterbuch." Quelle: Link
Maris B.
@wishmesh: Stimme zu. Andererseits - werden statische Variablen gespeichert, wenn die datenbankbasierte Zustandsmaschine aktiviert ist?
Abatishchev
1
Du hast Recht. Es scheint, dass der "statische Variablenansatz" in Web Garden und anderen Szenarien fehlschlagen kann.
Maris B.
@abatishchev Warum definieren Sie Ihre Variable nicht in Global.asax? Sie führen beim Zugriff auf die Variable bei jeder Anforderung ungewöhnliche Typumwandlungen durch.
Anirudha Gupta
@Gupta: Im Wesentlichen sind sowohl HttpContext als auch Global.asax Legacy-Ansätze. Statische Variablen sind im Allgemeinen besser. Aber jeder hat Vor- und Nachteile, siehe Kommentar oben. Letztendlich sollten Sie jedoch keine gemeinsam genutzten Variablen haben. HTTP ist zustandslos, ebenso wie Ihr Code.
Abatishchev
78

Technisch gesehen ist jede statische Variable oder Eigenschaft in einer Klasse an einer beliebigen Stelle in Ihrem Projekt eine globale Variable, z

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

Aber wie @SLaks sagt, können sie "möglicherweise" schlecht und gefährlich sein, wenn sie nicht richtig gehandhabt werden. In diesem obigen Beispiel hätten Sie beispielsweise mehrere Anforderungen (Threads), die versuchen, auf dieselbe Eigenschaft zuzugreifen. Dies könnte ein Problem sein, wenn es sich um einen komplexen Typ oder eine Sammlung handelt. Sie müssten eine Form der Sperrung implementieren.

Sonntag Eisenfuß
quelle
9
Meine Gegenstimme. Laut Microsoft ist dies eine bevorzugte Methode - die Verwendung globaler Variablen (statisch) aufgrund der Leistung. Das Anwendungsobjekt wird aus Gründen der Kompatibilität mit dem alten ASP verwendet. Lesen Sie hier mehr: Link . AFAIK sowohl statisch als auch Application erfordert Sperren, wenn Sie an Thread-Sicherheit und Parallelität denken. Wenn Application threadsicher ist, sind die Daten, auf die Sie zugreifen, möglicherweise nicht gesperrt.
Maris B.
Die statischen Klassen sind nicht sitzungssicher, d. H. Im selben Moment teilen sich 2 gleichzeitige Anfragen von 2 Benutzern dieselbe Variable, wodurch die Daten durcheinander gebracht werden. Um die Sicherheit der Benutzersitzung zu gewährleisten, muss etwas wie abatishchev erwähnt werden.
Vasil Popov
Ich stimme @Sunday zu und denke, dass diese als richtige Antwort markiert werden sollte. Der beste Weg, dies zu tun, ist jedoch die Implementierung eines thread-sicheren Singleton-Musters wie: csharpindepth.com/Articles/General/Singleton.aspx
Tohid
Das ist die beste Antwort.
Matheus Miranda
24

Sie können sie in die Anwendung einfügen:

Application["GlobalVar"] = 1234;

Sie sind nur innerhalb der aktuellen IIS / Virtual-Anwendung global. Dies bedeutet, dass sie in einer Webfarm lokal auf dem Server und in dem virtuellen Verzeichnis sind, das das Stammverzeichnis der Anwendung ist.

GvS
quelle
18

Für nicht statische Variablen habe ich sie wie folgt über das Anwendungsklassenwörterbuch sortiert :

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

Und im Controller:

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

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

    }
}

Auf diese Weise können wir globale Variablen in ASP.NET MVC haben :)

HINWEIS: Wenn Ihr Objekt keine Zeichenfolge ist, schreiben Sie einfach:

return View(HttpContext.Application["X"] as yourType);
Yasser Zamani
quelle
2
Es sollte beachtet werden, dass der Kern Ihrer Antwort lautet: "Verwenden Sie das Application Klassenwörterbuch.
Andrew Barber
@ YasserZamani das ist perfekt. aber wie ändere ich die globalen Variablen in Controller? Jedes Mal, wenn ich den Wert änderte, ging er bei anderen Anfragen verloren.
Shedom Wei
8

Sie können auch eine statische Klasse verwenden, z. B. eine Config-Klasse oder etwas in dieser Richtung ...

public static class Config
{
    public static readonly string SomeValue = "blah";
}
Ian P.
quelle
0

Der Stahl ist alles andere als heiß, aber ich habe die Lösung von @ abatishchev mit der Antwort aus diesem Beitrag kombiniert und bin zu diesem Ergebnis gekommen. Hoffe es ist nützlich:

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
quelle