调用HttpContext.Request时如何避免HttpException?

时间:2014-04-18 01:56:08

标签: c# asp.net httpcontext

如果在全局启动中调用,则HttpContext.Request抛出

public HttpRequest get_Request()
{
    if (this.HideRequestResponse)
    {
        throw new HttpException(SR.GetString("Request_not_available"));
    }
    return this._request;
}

这实际上是记录在案的

  

如果在HttpRequest对象不可用时尝试使用此属性,ASP.NET将引发异常。例如,在Global.asax文件的Application_Start方法中或在从Application_Start方法调用的方法中都是如此。那时还没有创建HTTP请求。

有没有办法检查HttpContext.Request是否处于可以检索而不抛出异常的状态?实际上我想写一个TryGetRequest辅助方法。

  • 反思不是一种选择。它需要是一个公共API。
  • 我无法访问应用程序上下文。这是通用的日志记录代码。因此,在启动完成时设置一些标志不是一个选项

3 个答案:

答案 0 :(得分:5)

当观察到 deostroll 时,它是合理的,实际上可能需要依赖ASP.NET应用程序生命周期来确定当前HttpRequest何时可用。通用日志记录代码可能至少依赖于HttpContext.Current或对当前HttpContext实例的其他引用。如果该假设成立,则可以实现HttpModule,以便在HttpContext.Items事件触发时在BeginRequest集合中存储标记。静态TryGetRequest辅助方法可以测试该标志的存在,以确定使用HttpContext.Request是否安全。

也许是这样:

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
}

该模块必须在web.config中注册(假设IIS 7.0集成管道):

  <system.webServer>
    <modules>
      <add name="HttpRequestHelper" type="Utility.HttpRequestHelper" />
    </modules>
  </system.webServer>

日志记录代码将使用如下的辅助方法:

HttpRequest request;
if (HttpRequestHelper.TryGetRequest(HttpContext.Current, out request))
    LogWithRequest(request, message);
else
    LogWithoutRequest(message);

该实现不依赖于私有API或反射。它依赖于一个标志,但状态信息仍保留在HttpContext实例中,并且封装良好。

答案 1 :(得分:2)

为什么不用try,catch块将调用包装到HttpContext.Request,然后你可以捕获异常并相应地修改你的行为。

答案 2 :(得分:2)

不使用反射

是不可能的