Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does making Application_Start a static method (a recommendation of FxCopAnalyzer) cause 404 errors?

Tags:

c#

.net-4.7.2

Visual Studio recommended I install the new Microsoft.CodeAnalysis.FxCopAnalyzers in my project. It nicely identifies a number of improvements in the source, but one of its recommendations is:

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

I examined the routine and sure enough, FxCopAnalyzer was right. So I changed:

protected void Application_Start()

to

protected static void Application_Start()

However, when I make that change, I now get this:

HTTP Error 403.14 - Forbidden

The Web server is configured to not list the contents of this directory.

If I take out "static", it works again. But I'm a little confused why the framework cares if this method is static.

like image 891
Glenn Avatar asked Jan 19 '26 02:01

Glenn


1 Answers

This was such an interesting question. It took me a while to understand the Asp.Net bootstrapping pipeline. I will not go into detail so much because it would take a lot so I will leave the details to OP.

Basically, Asp.Net framework dynamically creates an assembly and creates a dynamically created type which inherits your MvcApplication.

So here is the default MvcApplication

public class MvcApplication : HttpApplication {

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

So what do I mean by Asp.Net framework dynamically creating another assembly and a type? You will notice that by checking the following code→ Let us modify Application_Start method:

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...
}

Where does ASP.global_asax type is created? You will need to dig deep into source code but let me give you a hint

So how does the actual ASP.global_asax looks like?

[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));
        }
    }
}

Finally, we can move onto the actual answer: Why does making Application_Start static make the application behave in an unexpected way?

In HttpApplicationFactory class, which is used in the bootstrapping your application, there is the following line of code

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

The puzzle is solved at _theApplicationType. Please remember that this is of ASP.global_asax type. Your static method Application_Start is defined in MvcApplication type so reflection will not find it through _theApplicationType and as a result it will not be assigned to be called when application starts.

Here is a simple code to check this.

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);
like image 74
Hasan Emrah Süngü Avatar answered Jan 20 '26 19:01

Hasan Emrah Süngü