为什么将Application_Start设为静态方法(FxCopAnalyzer的建议)会导致404错误? - c#

Visual Studio建议我在项目中安装新的Microsoft.CodeAnalysis.FxCopAnalyzers。它很好地标识了源代码中的许多改进,但是其建议之一是:

CA1822: Member Application_Start does not access instance data and can be marked as static (Shared in `VisualBasic`).

我检查了例程,并且肯定地,FxCopAnalyzer是正确的。所以我改变了:

protected void Application_Start()

protected static void Application_Start()

但是,当我进行更改时,现在得到的是:

HTTP错误403.14-禁止
Web服务器配置为不列出此目录的内容。

如果我取出“静态”,它将再次起作用。但是我有些困惑,为什么框架关心这种方法是否是静态的。

参考方案

这是一个有趣的问题。我花了一些时间来了解Asp.Net引导管道。我将不做太多详细介绍,因为这会花费很多时间,因此我将把细节留给OP。

基本上,Asp.Net框架会动态创建一个程序集并创建一个继承自MvcApplication的动态创建的类型。

所以这是默认的MvcApplication

public class MvcApplication : HttpApplication {

    public static void Application_Start() {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

那么,Asp.Net框架动态创建另一个程序集和一个类型意味着什么?您会注意到,通过检查以下代码→
让我们修改Application_Start方法:

public static void Application_Start() {
    var whatIsMyType =  GetType();
    //You will see that our actual type is of ASP.global_asax,
    //which inherits  MvcApplication, which inherits  HttpApplication      
    //Other Stuff...
}

ASP.global_asax类型在哪里创建?您将需要深入研究源代码,但让我给您一个hint

那么实际的ASP.global_asax看起来如何?

[System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
public class global_asax : global::<YourNameSpace>.MvcApplication {

    private static bool @__initialized;

    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public global_asax() {
        if ((global::ASP.global_asax.@__initialized == false)) {
            global::ASP.global_asax.@__initialized = true;
        }
    }

    protected System.Web.Profile.DefaultProfile Profile {
        get {
            return ((System.Web.Profile.DefaultProfile)(this.Context.Profile));
        }
    }
}

最后,我们可以进入实际答案:为什么将Application_Start设为静态会导致应用程序以意外的方式运行?

在引导应用程序的HttpApplicationFactory类中,有以下代码行

methods = _theApplicationType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
foreach (MethodInfo m in methods) {
    if (ReflectOnMethodInfoIfItLooksLikeEventHandler(m))
        handlers.Add(m);
}

难题在_theApplicationType处解决。请记住,这是ASP.global_asax type的。您的静态方法Application_Start是用MvcApplication类型定义的,因此反射将无法通过_theApplicationType找到它,因此,当应用程序启动时,不会将其分配给调用。

这是检查此代码的简单代码。

public class BaseClass {
    public static void StaticMethodInBaseClass() {
    }
}

public class DerivedClass {
    public void DerivedClassMethod() {
    }
}

//You will not get `StaticMethodInBaseClass` here
var methods = typeof(DerivedClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

LeetCode题解计算机为什么是基于二进制的?

可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制

LeetCode题解统计城市的所有灯泡

这个是我刚毕业的时候,一个真实的面试题,这是一个开放题。题目描述:想办法,将一个城市的所有灯泡数量统计出来。题解:费米估算法1、如果某个城市常驻人口有1000万2、假设每5人居住在一套房里,每套房有灯泡5只,那么住宅灯泡共有1000万只3、假设公众场所每10人共享一只灯泡,那么共有100万只4、主要的这两者相加就得出了1100万只当然实际上这是估算的,具体应…

LeetCode题解黑白圆盘

一个圆盘被涂上了黑白二色,两种颜色各占一个半圆。圆盘以一个未知的速度、按一个未知的方向旋转。你有一种特殊的相机可以让你即时观察到圆上的一个点的颜色。你需要多少个相机才能确定圆盘旋转的方向?题解:可以用一个相机即可

LeetCode题解圆上任取三点构成锐角三角形的概率

来自字节跳动的一道几何题题解:1/4

LeetCode题解深度优先遍历和回溯的关系?

深度优先遍历的范围更大还是回溯的范围更大?为什么?题解:我的理解是:dfs是回溯思想的一种体现- 回溯:是在整个搜索空间中搜索出可行解,在搜索过程中不断剪枝回退,这是回溯的思想,这个搜索空间并没有限制于特定的数据结构。- dfs:dfs是指特定的数据结构中如图,树(特殊的图)中搜索答案,范围限制在了特定的数据结构。个人拙见。