我认为MvcApplication
是全球singleton。我想在控制器中获取MvcApplication
的实例。然后我将以下代码放在控制器中:
MvcApplication app = HttpContext.Current.Application as MvcApplication;
它给了我一个错误:
错误2'System.Web.HttpContextBase'不包含'Current'的定义,并且没有扩展方法'Current'可以找到接受类型'System.Web.HttpContextBase'的第一个参数(你是否错过了使用指令或程序集引用?)
为什么呢?如何访问控制器中的MvcApplication
?
答案 0 :(得分:43)
MvcApplication!= singleton
这意味着上面的所有答案都会忽略这一点,如果你错误地认为访问同一个实例会让你陷入严重的麻烦,而事实上会有几个。
你的第一个假设是无效的:与(非常 - 只是在这里看到其他答案作为证据)普遍的看法相反,MvcApplication不是一个全球性的单身人士。该类被多次实例化,每个“管道”一个实例,因此性能计数器“管道实例计数”告诉您当前有多少MvcApplication实例被活化。添加一个默认的ctor并自己证明:
public MvcApplication()
{
Trace.WriteLine(this.GetHashCode());
}
Debug会破坏该行或在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怪异
HttpApplication类及其事件的设计非常奇怪,这可能是因为它与某些旧的基于COM的ASP页面的一些松散的向后设计兼容性。在那里,应用程序对象实际上只创建了一次,这肯定是与Asp.Net相关的错误信念的起源。 HttpApplication奇怪的一个例子:
protected void Application_Start()
{
}
请注意,没有涉及覆盖!
总之,应用程序实例在大多数情况下可能没什么兴趣,我看不出它与保持状态有关的情况,因为它的状态将由处理的任意子集共享。因此,Matt提到的完全正确的方式访问它可能不是经常需要的。
答案 1 :(得分:33)
试试这个:
var app = HttpContext.Current.ApplicationInstance as MvcApplication;
答案 2 :(得分:16)
我认为原始代码不起作用的原因是因为HttpContext既是Controller的属性又是它自己的类。在Controller的子类中,HttpContext将解析为属性并产生提到的错误。为了解决这个问题,请使用它的完全限定名称显式引用HttpContext类:
System.Web.HttpContext.Current.Application
或者,由于HttpContext属性已经返回当前的HttpContext实例,您可以使用:
HttpContext.Application