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

本文关键字:HttpException Request HttpContext 调用 | 更新日期: 2023-09-27 17:58:47

所以 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。
  • 我无权访问应用程序上下文。 这是通用日志记录代码。因此,在启动完成后设置一些标志不是一种选择

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

正如deoroll所观察到的,依靠 ASP.NET 应用程序生命周期来确定当前HttpRequest何时可用是合理的,实际上可能有必要。 通用日志记录代码可能至少依赖于对当前HttpContext实例的HttpContext.Current或其他一些引用。 如果该假设成立,则可以实现一个HttpModule,该在BeginRequest事件触发时在HttpContext.Items集合中存储标志。 静态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实例中,并且封装得很好。

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

不使用反射是不可能的