2009-06-30 11 views
20

Myślę, że MvcApplication jest globalnym singleton. Chcę uzyskać instancję MvcApplication w kontrolerze. Następnie umieścić następujący kod w kontrolerze:Jak uzyskać instancję "MvcApplication" w kontrolerze ASP.NET?

MvcApplication app = HttpContext.Current.Application as MvcApplication; 

Daje mi błąd:

Error 2 'System.Web.HttpContextBase' does not contain a definition for 'Current' and no extension method 'Current' accepting a first argument of type 'System.Web.HttpContextBase' could be found (are you missing a using directive or an assembly reference?)

Dlaczego? Jak uzyskać dostęp do MvcApplication w kontrolerze?

+0

Czy mógłbyś wytłumaczyć, co chcesz z tym osiągnąć? Może jest inny, jeszcze lepszy sposób na wykonanie tego zadania. – griegs

+0

co chcę: z moją aplikacją mvc, chcę uzyskać wartość zapytania, gdy użytkownik uzyskuje dostęp do strony głównej, takiej jak: http: // localhost: 2929 /? Source = abc. następnie chcę ustawić to źródło = abc w MvcApplication. public class MvcApplication: System.Web.HttpApplication { public string Źródło; // ..... } Następnie chcę źródłowy dostępny dla wszystkich widzenia: Chcę uzyskać dostęp do źródła w konstruktorze kontrolera jak: MvcApplication app = HttpContext.Current.Application jak MvcApplication łańcuch src = app.Source ; ... – KentZhou

+2

Ostrzeżenie: Zanim opuścisz ten wątek z zaznaczoną odpowiedzią, przeczytaj moją odpowiedź poniżej, ponieważ pozostałe odpowiedzi, w tym zaznaczone, są oparte na całkowicie błędnym założeniu, że MvcApplication jest globalnym singletonem. – citykid

Odpowiedz

31

Spróbuj tego:

var app = HttpContext.ApplicationInstance as MvcApplication; 
+0

Próbuję go w konstruktorze kontrolera, jak:
var app = HttpContext.ApplicationInstance jako MvcApplication;
następnie dostałem błąd na stronie:
Błąd serwera w aplikacji "/".
....
Linia 35: var app = HttpContext.ApplicationInstance jako MvcApplication; – KentZhou

+0

Należy unikać dostępu do właściwości kontrolera, takich jak HttpContext lub ControllerContext w konstruktorze. Wypróbuj to samo w Action lub OnActionExecuting() –

16

wierzę, dlaczego oryginalny kod nie działa, ponieważ jest HttpContext jest zarówno właściwością Controller i własnej klasy. W podklasie kontrolera HttpContext rozwiąże właściwość i wygeneruje wspomniany błąd. Aby dostać się wokół niego, jawnie odwołać klasy HttpContext z jego pełna nazwa:

System.Web.HttpContext.Current.Application 

Albo, ponieważ nieruchomość HttpContext już wraca prąd HttpContext instancji, można użyć:

HttpContext.Application 
40

MvcApplication! = singleton

co oznacza, że ​​wszystkie powyższe odpowiedzi pomijają punkt i mogą spowodować poważne kłopoty, jeśli niesłusznie uwierzą w dostęp do tej samej instancji, w rzeczywistości będzie ich kilka.

Twoje pierwsze założenie jest nieważne: w przeciwieństwie do (bardzo - widzisz tylko inne odpowiedzi tutaj jako dowód) rozpowszechnionego przekonania, MvcApplication nie jest globalnym singletonem. Ta klasa jest tworzona kilka razy, jedna instancja na "potok", więc licznik wydajności "liczba instancji pipeline" pokazuje, ile instancji MvcApplication jest aktualnie uważanych za żywych. Dodaj domyślnego ctor i udowodnij to sobie:

public MvcApplication() 
{ 
    Trace.WriteLine(this.GetHashCode()); 
} 

Debugowanie przerwać linię lub obejrzeć różne kody skrótu w DebugViewer. Aby wymusić wzrost liczby instancji potoku, należy utworzyć metodę z Thread.Sleep (5000), Asp.Net uruchomi następnie nową instancję po kolejnym wywołaniu kolejnego żądania http.

Solution - Jak instancję singletons w aplikacji ASP.NET (MVC lub WebForms)

Jeśli klasa MvcApplication ma jednak metodę Application_Start() to metoda ta nazywa się w rzeczywistości tylko raz, proces szeroko. Możesz tam ustawić pola statyczne. Po prostu umieść je w dowolnej klasie, zazwyczaj MvcApplication jest dobrym konwencjonalnym wyborem i dostęp do nich. Jak

MvcApplication.MySingleValue = 72; 
MvcApplication.ActivePlayersCount = 3400; 
var n = MvcApplication.ActivePlayersCount; 
... 

HttpApplication niesamowitość

Konstrukcja klasy HttpApplication i jego wydarzenia jest dość dziwne, który przypuszczalnie ma swoją przyczynę w jakimś luźnym rodzaju kompatybilności wstecz projektu do bardzo starych COM oparte stron ASP. Tam obiekt aplikacji został utworzony tylko raz, co z pewnością jest źródłem błędnego przekonania związanego z Asp.Net.Przykładem dziwności HttpApplication:

protected void Application_Start() 
{ 
} 

Zauważ, że nie jest zaangażowany przesłanianie!

Podsumowując, instancje aplikacji mogą być mało przydatne przez większość czasu, nie widzę scenariusza, w którym mogłoby się to zdarzyć w celu utrzymania stanu, ponieważ jego stan byłby współdzielony przez arbitralny podzbiór obsługiwanych żądań. Tak więc dostęp do niego w zupełnie nowy sposób, o którym wspomniał Matt, może nie być wymagany zbyt często.

Powiązane problemy