如何在ASP.NET控制器中获取"MvcApplication"实例?

Ken*_*hou 22 asp.net-mvc

我认为MvcApplication是一个全球单身人士.我想获得MvcApplication控制器中的实例.然后我将以下代码放在控制器中:

MvcApplication app = HttpContext.Current.Application as MvcApplication;
Run Code Online (Sandbox Code Playgroud)

它给了我一个错误:

错误2'System.Web.HttpContextBase'不包含'Current'的定义,并且没有扩展方法'Current'可以找到接受类型'System.Web.HttpContextBase'的第一个参数(你是否缺少using指令或者装配参考?)

为什么?如何MvcApplication在控制器中访问?

cit*_*kid 43

MvcApplication!=单身人士

这意味着上面的所有答案都会忽略这一点,如果你错误地认为访问同一个实例会让你陷入严重的麻烦,而事实上会有几个.

你的第一个假设是无效的:与(非常 - 只是在这里看到其他答案作为证据)普遍的看法相反,MvcApplication不是一个全球性的单身人士.该类被多次实例化,每个"管道"一个实例,因此性能计数器"管道实例计数"告诉您当前有多少MvcApplication实例被活化.添加默认ctor并自行证明:

public MvcApplication()
{
    Trace.WriteLine(this.GetHashCode());
}
Run Code Online (Sandbox Code Playgroud)

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;
...
Run Code Online (Sandbox Code Playgroud)

HttpApplication很奇怪

HttpApplication类及其事件的设计非常奇怪,这可能是因为它与某些旧的基于COM的ASP页面的一些松散的向后设计兼容性.在那里,应用程序对象实际上只创建了一次,这肯定是与Asp.Net相关的错误信念的起源.HttpApplication奇怪的一个例子:

protected void Application_Start()
{
}
Run Code Online (Sandbox Code Playgroud)

请注意,没有涉及覆盖!

总而言之,应用程序实例在大多数情况下可能不太重要,我看不出任何可能与保持状态相关的情况,因为其状态将由处理的任意子集共享.因此,以Matt提到的完全精细的方式访问它可能不是经常需要的.


eu-*_*-ne 34

试试这个:

var app = HttpContext.Current.ApplicationInstance as MvcApplication;
Run Code Online (Sandbox Code Playgroud)


小智 16

我相信原始代码不起作用的原因是因为HttpContext既是Controller的属性又是它自己的类.在Controller的子类中,HttpContext将解析为属性并产生提到的错误.为了解决它,使用它的完全限定名称显式引用HttpContext类:

System.Web.HttpContext.Current.Application
Run Code Online (Sandbox Code Playgroud)

或者,由于HttpContext属性已经返回当前的HttpContext实例,您可以使用:

HttpContext.Application
Run Code Online (Sandbox Code Playgroud)