So HttpContext.Request throws if called within a global start
public HttpRequest get_Request()
{
if (this.HideRequestResponse)
{
throw new HttpException(SR.GetString("Request_not_available"));
}
return this._request;
}
This is actually documented
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.
Is there a way of checking if a HttpContext.Request is in a state that it can be retrieved without throwing the exception? Effectively I want to write a TryGetRequest
helper method.
HTTPContext. Current is a static property. This property is a static property of the HttpContext class. The property stores the HttpContext instance that applies to the current request. The properties of this instance are the non-static properties of the HttpContext class.
The HttpContext is NOT thread safe, accessing it from multiple threads can result in exceptions, data corruption and generally unpredictable results.
From ASP.NET 4.5 and after, Current HttpContext is passed through CallContext instead of [ThreadStatic] , so context remains available through out async calls in single logical context instead of current thread as each async call may end up on different threads.
When an HTTP request arrives at the server, the server processes the request and builds an HttpContext object. This object represents the request which your application code can use to create the response.
As deostroll observed, it is reasonable and may in fact be necessary to rely on the ASP.NET application lifecycle to determine when the current HttpRequest has become available. The generic logging code is presumably dependent at the very least on HttpContext.Current
or some other reference to the current HttpContext
instance. If that assumption holds true, then an HttpModule
can be implemented that stores a flag in the HttpContext.Items
collection when the BeginRequest
event fires. The static TryGetRequest
helper method can test for the presence of that flag to determine whether it is safe to use HttpContext.Request
.
Perhaps like this:
public class HttpRequestHelper : IHttpModule
{
private const string HttpRequestIsAvailable = "HttpRequestIsAvailable";
public static bool TryGetRequest(HttpContext context, out HttpRequest request)
{
request = null;
if (context != null)
{
if (context.Items.Contains(HttpRequestIsAvailable))
request = context.Request;
}
return (request != null);
}
#region IHttpModule
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
}
private void context_BeginRequest(object sender, EventArgs e)
{
((HttpApplication)sender).Context.Items.Add(HttpRequestIsAvailable, true);
}
#endregion
}
The module must be registered in web.config (assuming IIS 7.0 integrated pipeline):
<system.webServer>
<modules>
<add name="HttpRequestHelper" type="Utility.HttpRequestHelper" />
</modules>
</system.webServer>
The logging code would use the helper method like this:
HttpRequest request;
if (HttpRequestHelper.TryGetRequest(HttpContext.Current, out request))
LogWithRequest(request, message);
else
LogWithoutRequest(message);
The implementation does not rely on private API's or reflection. It relies on a flag, but the state information remains with the HttpContext
instance and is well encapsulated.
Why not wrap the call to HttpContext.Request
with a try, catch block then you can catch the exception and modify your behaviour accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With