asp.net-mvc 如何在 ASP.NET 控制器中获取“MvcApplication”实例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1066350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get an 'MvcApplication' instance in ASP.NET controller?
提问by KentZhou
I think MvcApplicationis a global singleton. I want to get the instance of MvcApplicationin the controller. Then I put the following code in controller:
我认为MvcApplication是全局单例。我想获取MvcApplication控制器中的实例。然后我将以下代码放入控制器:
MvcApplication app = HttpContext.Current.Application as MvcApplication;
It gives me an error:
它给了我一个错误:
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?)
错误 2“System.Web.HttpContextBase”不包含“Current”的定义,并且找不到接受“System.Web.HttpContextBase”类型的第一个参数的扩展方法“Current”(您是否缺少 using 指令或组装参考?)
Why? How do I access MvcApplicationin the controller?
为什么?如何MvcApplication在控制器中访问?
回答by citykid
MvcApplication != singleton
MvcApplication != 单例
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.
这意味着上面的所有答案都没有抓住重点,如果您错误地认为访问同一个实例,而实际上会有多个实例,则会给您带来严重的麻烦。
Your very first assumption is not valid: Contrary to (very - just see the other answers here as a proof) widespread belief, MvcApplication is NOT a global singleton. The class is instantiated several times, one instance per "pipeline", so the performance counter "pipeline instance count" tells you how many instances of MvcApplication are currently consdidered alive. Add a default ctor and prove this yourself:
你的第一个假设是无效的:与(非常 - 只是在这里看到其他答案作为证据)普遍的信念相反,MvcApplication 不是全局单例。该类被实例化多次,每个“管道”一个实例,因此性能计数器“管道实例计数”告诉您当前认为有多少 MvcApplication 实例处于活动状态。添加一个默认的ctor并自己证明这一点:
public MvcApplication()
{
Trace.WriteLine(this.GetHashCode());
}
Debug break the line or watch the various hash codes in DebugViewer. To force pipeline instance count going up create a method with Thread.Sleep(5000), Asp.Net will then fire up a new instance once you make another http request in parallel.
调试断线或在 DebugViewer 中观察各种哈希码。要强制管道实例计数上升,请使用 Thread.Sleep(5000) 创建一个方法,一旦您并行发出另一个 http 请求,Asp.Net 将启动一个新实例。
Solution - How to instantiate singletons in Asp.Net applications (MVC or WebForms)
解决方案 - 如何在 Asp.Net 应用程序(MVC 或 WebForms)中实例化单例
If your MvcApplication class however has an Application_Start() method then this method is called in fact only once, process wide. You can set static fields there. Simply put them to any class, typically MvcApplication is a good conventional choice, and access them. Like
然而,如果你的 MvcApplication 类有一个 Application_Start() 方法,那么这个方法实际上只在进程范围内调用一次。您可以在那里设置静态字段。简单地将它们放到任何类中,通常 MvcApplication 是一个很好的常规选择,并访问它们。喜欢
MvcApplication.MySingleValue = 72;
MvcApplication.ActivePlayersCount = 3400;
var n = MvcApplication.ActivePlayersCount;
...
HttpApplication weirdness
HttpApplication 的怪异
The design of the HttpApplication class and its events is quite strange, which presumably has its reason in some loose sort of backwards design compatibility to very old COM based ASP pages. There the application object was in fact created only once, which is surely the origin of the wrong belief related to Asp.Net. An example of the HttpApplication strangeness:
HttpApplication 类及其事件的设计非常奇怪,这大概是由于对非常旧的基于 COM 的 ASP 页面的某种松散的向后设计兼容性。那里的应用程序对象实际上只创建了一次,这肯定是与 Asp.Net 相关的错误信念的起源。HttpApplication 奇怪的一个例子:
protected void Application_Start()
{
}
Note that there is no override involved!
请注意,不涉及覆盖!
In summary, the application instances might be of minor interest most of the time, I can see no scenario were it could become relevant to hold state, as its state would be shared by an arbitrary subset of requests handled. So accessing it in the completely fine way as mentioned by Matt might not be required too often.
总而言之,应用程序实例在大多数情况下可能是次要的,我看不出它与保持状态相关的情况,因为它的状态将由处理的请求的任意子集共享。因此,可能不需要太频繁地以 Matt 提到的完全正确的方式访问它。
回答by eu-ge-ne
Try this:
尝试这个:
var app = HttpContext.Current.ApplicationInstance as MvcApplication;
回答by Matt Hopkins
I believe the reason why the original code didn't work is because HttpContext is both a property of Controller and its own class. Within a subclass of Controller, HttpContext will resolve to the property and produce the error mentioned. To get around it, explicitly reference the HttpContext class with it's fully qualified name:
我相信原始代码不起作用的原因是因为 HttpContext 既是 Controller 的属性又是它自己的类。在 Controller 的子类中,HttpContext 将解析为该属性并产生提到的错误。要绕过它,请使用完全限定名称显式引用 HttpContext 类:
System.Web.HttpContext.Current.Application
Or, since the HttpContext property already returns the current HttpContext instance, you could use:
或者,由于 HttpContext 属性已经返回当前 HttpContext 实例,您可以使用:
HttpContext.Application

