Подтвердить что ты не робот

Как получить экземпляр "MvcApplication" в контроллере ASP.NET?

Я думаю, что MvcApplication является глобальным singleton. Я хочу получить экземпляр MvcApplication в контроллере. Затем я ввел следующий код в контроллер:

MvcApplication app = HttpContext.Current.Application as MvcApplication;

Это дает мне ошибку:

Ошибка 2 "System.Web.HttpContextBase" не содержит определения для "Current" и не существует метода расширения "Current", принимающего первый аргумент типа "System.Web.HttpContextBase" (вам не хватает использования директива или ссылка на сборку?)

Почему? Как получить доступ к MvcApplication в контроллере?

4b9b3361

Ответ 1

Попробуйте следующее:

var app = HttpContext.ApplicationInstance as MvcApplication;

Ответ 2

MvcApplication!= singleton

что означает, что все ответы выше пропустят точку и вызовут вас серьезные проблемы, если вы ошибочно полагаете, что хотите получить доступ к одному экземпляру, в то время как на самом деле их будет несколько.

Ваше первое предположение неверно: вопреки (очень просто см. другие ответы здесь как доказательство) широко распространенное мнение, MvcApplication НЕ является глобальным синглом. Класс создается несколько раз, по одному экземпляру на "конвейер", поэтому счетчик производительности "count экземпляра конвейера" сообщает вам, сколько экземпляров MvcApplication в настоящее время подсчитано живым. Добавьте значение по умолчанию ctor и убедитесь сами:

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

Отладка разбивает строку или просматривает различные хэш-коды в DebugViewer. Чтобы принудительно увеличить счетчик контуров, создайте метод с помощью Thread.Sleep(5000), Asp.Net будет запускать новый экземпляр, как только вы сделаете другой запрос http параллельно.

Решение. Как создавать экземпляры синглетонов в приложениях ASP.NET(MVC или WebForms)

Если ваш класс MvcApplication однако имеет метод Application_Start(), то этот метод вызывается фактически только один раз, процесс широкий. Вы можете установить там статические поля. Просто поместите их в любой класс, обычно MvcApplication - хороший традиционный выбор и доступ к ним. Как

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

HttpApplication weirdness

Конструкция класса HttpApplication и его событий довольно странная, что, по-видимому, имеет свою причину в некотором свободном виде обратной совместимости дизайна с очень старыми ASP-страницами на основе COM. Там объект приложения был создан только один раз, что, несомненно, является причиной неправильного убеждения, связанного с Asp.Net. Пример странности HttpApplication:

protected void Application_Start()
{
}

Обратите внимание, что не задействовано переопределение!

В целом, экземпляры приложений могут быть в основном незначительными, я не вижу никакого сценария, поскольку это могло бы стать актуальным для сохранения состояния, поскольку его состояние будет разделяться произвольным подмножеством обработанных запросов. Поэтому доступ к нему совершенно прекрасным способом, как упоминалось Мэттом, может не потребоваться слишком часто.

Ответ 3

Я считаю, что причина, по которой исходный код не работал, заключается в том, что HttpContext является одновременно свойством Controller и его собственного класса. В рамках подкласса Controller HttpContext будет разрешать свойство и вызывать указанную ошибку. Чтобы обойти это, явным образом ссылаюсь на класс HttpContext с полным именем:

System.Web.HttpContext.Current.Application

Или, поскольку свойство HttpContext уже возвращает текущий экземпляр HttpContext, вы можете использовать:

HttpContext.Application