Вопрос по asp.net-mvc – Как получить экземпляр MvcApplication в контроллере ASP.NET?

21

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

MvcApplication app = HttpContext.Current.Application as MvcApplication;

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

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?)

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

Не могли бы вы объяснить, чего вы пытаетесь достичь этим? Может быть, есть другой, даже лучший, способ выполнить задачу. griegs
Предупреждение: Прежде чем покинуть эту ветку с помеченным ответом, прочитайте мой ответ ниже, потому что все остальные ответы, включая помеченный, основаны на совершенно неверном предположении, что MvcApplication является глобальным синглтоном. citykid
то, что я хочу: в моем приложении mvc я хочу получить значение строки запроса, когда пользователь получает доступ к домашней странице, например:localhost:2929/?source=abc, тогда я хочу установить этот источник = abc в MvcApplication. открытый класс MvcApplication: System.Web.HttpApplication {открытая строка Source; // .....} Затем я хочу, чтобы источник был доступен для всех представлений: я хочу получить доступ к источнику в конструкторе контроллера, например: MvcApplication app = HttpContext.Current.Application as MvcApplication string Src = app.Source; ... KentZhou

Ваш Ответ

3   ответа
32

var app = HttpContext.Current.ApplicationInstance as MvcApplication;
Я пробую это в конструкторе контроллера, например: & lt; br / & gt; var app = HttpContext.ApplicationInstance as MvcApplication; & lt; br / & gt; затем я получил сообщение об ошибке на странице: & lt; br / & gt; Ошибка сервера в «/»; Применение & л;. Ш / & GT; .... & л; ш / & GT; Строка 35: var app = HttpContext.ApplicationInstance as MvcApplication; KentZhou
Вы должны избегать доступа к свойствам контроллера, таким как HttpContext или ControllerContext в конструкторе. Попробуйте то же самое в действии или OnActionExecuting ()
41

MvcApplication != singleton

which means that all answers above miss the point and will get you into serious trouble if you wrongly believe to access the same instance while in fact there will be several.

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

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

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

Solution - How to instantiate singletons in Asp.Net applications (MVC or 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()
{
}

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

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

16

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

System.Web.HttpContext.Current.Application

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

HttpContext.Application

Похожие вопросы