سؤال

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
هل كانت مفيدة؟

المحلول 3

It is not possible without using reflection

نصائح أخرى

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top