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

标签 c# asp.net httpcontext

所以 HttpContext.Request如果在全局启动内调用则抛出

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

这实际上是有记录的

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.

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

  • 反射(reflection)不是一种选择。它需要是一个公共(public) API。
  • 我无权访问应用程序上下文。这是通用的日志记录代码。所以在启动完成时设置一些标志不是一个选项

最佳答案

正如 deostroll 所观察到的,依赖 ASP.NET 应用程序生命周期来确定当前 HttpRequest 何时可用是合理的,实际上可能是必要的。通用日志记录代码可能至少依赖于 HttpContext.Current 或对当前 HttpContext 实例的一些其他引用。如果该假设成立,则可以实现 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);

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

关于c# - 调用 HttpContext.Request 时如何避免 HttpException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23146254/

相关文章:

c# - 如何学习 MVC——*不*在网络环境中

c# - 如何在 .NET Core 应用程序 docker 镜像中包含依赖项?

C# 如何通过 WebBrowser 自动点击按钮

c# - 如何从自定义事件处理程序返回项目

c# - System.Net.Http.Formatting.dll 导致 Newtonsoft.Json 出现问题

asp.net - 源代码管理中的 .vs\config\applicationhost.config

c# - 如何在 IIS 托管的 WCF 应用程序上执行一些初始启动代码?

c# - MVC 模拟 (Moq) - HttpContext.Current.Server.MapPath

asp.net-mvc-2 - Azure 中的 ControllerContext 与 HttpContext

asp.net-mvc - 使用 ASP.NET MVC 的 HttpContext.Items