It is not possible without using reflection
How to avoid a HttpException when calling HttpContext.Request?
-
05-07-2023 - |
Question
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.
- Reflection is not an option. It needs to be a public API.
- I dont have access to the application context. this is generic logging code. So setting some flag when startup has finished is not an option
Solution 3
OTHER TIPS
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.