Monthly Archives: May 2015

Early access to HttpRequest in ASP.NET application

This is I see question often asked by people working on legacy applications. When IIS Integrated application mode was introduced, there were couple of breaking changes that caused (badly designed) access to web request to crash.

Applications which used to access HttpRequest early, in Application_Start greet visitors with an exception:

Request is not available in this context

In simple words, request is not yet available in this stage of execution. It will be available later. Documentation for HttpContext.Request property states:

ASP.NET will throw an exception if you try to use this property when the HttpRequest object is not available. For example, this would be true in the Application_Start method of the Global.asax file, or in a method that is called from the Application_Start method. At that time no HTTP request has been created yet.

There are many suggestions that involve catching the exception, checking message or other properties and make a decision based on that. While this will work, it’s not good approach for number of reasons.

Most important of which, it will negatively impact performance of your application, which is explained in this MSDN article.

Checking message is not safe, since different language version of .NET framework may be used, with localized messages. Or the message can be changed in updated version of .NET framework.

In the end, determining that Request is not always enough. One may decide to allow this, if information in the request is not critical, but some (awful) code may require the request to properly perform the initialization.

Workaround is simple enough, that I’m amazed there are so many proposals for what I’ve described above.

  1. Move initialization from Application_Start to Application_BeginRequest.
  2. Since request handling method executes on each request, make sure it’s executed only once
public void Application_BeginRequest()
{
    DoStartup();
}

private static bool _startupPerformed = false;
private static object _startupLock = new object();
private void DoStartup()
{
    if (!_startupPerformed)
    {
        lock (_startupLock)
        {
            if (!_startupPerformed)
            {
                _startupPerformed = true;
                // Initialize here
            }
        }
    }
}