尝试访问request.url时,ASP.NET HTTPMODULE失败了



我有一个HttpModule,可以使用每个HttpRequest处理一些自定义逻辑,并且由于某些原因,在极少数情况下,当我尝试访问HttpRequest.Url时,它会引发NullReferenceException错误。

访问Url之前,我要检查HttpContext是否存在,并且Request对象不是null。这是堆栈跟踪:

[NullReferenceException: Object reference not set to an instance of an object.] 
    System.Web.Hosting.IIS7WorkerRequest.GetQueryStringRawBytes() +55 
    System.Web.HttpRequest.get_QueryStringText() +76 
    System.Web.HttpRequest.BuildUrl(Func`1 pathAccessor) +42 
    System.Web.HttpRequest.get_Url() +88 
    MyHttpModule.BeginRequestEventHandler(Object sender, EventArgs e) at +xx      
    System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +175 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +168 

我还检查了.NET源以获取其他信息,但无法找到无效的地方:

https://referencesource.microsoft.com/#system.web/hosting/iis7workerrequest.cs,68b12222224e7bd28

这是代码:

public class MyHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += this.BeginRequestEventHandler;
    }
    private void BeginRequestEventHandler(object sender, EventArgs e)
    {
        var httpContext = ((HttpApplication)sender).Context;
        if (httpContext == null || httpContext.Request == null)
        {
            return;
        }
        var url = httpContext.Request.Url;
        // process url
    }
}

这种情况在极少数情况下发生,但只要在处理常规HTTP请求中发生。

您可以尝试从HttpContext.Current获得HttpContext吗?

public class MyHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += this.BeginRequestEventHandler;
    }
    private void BeginRequestEventHandler(object sender, EventArgs e)
    {
        var httpContext = HttpContext.Current;
        ...
    }
}

正如我们从堆栈跟踪中看到的那样,当.NET Framework尝试从上下文中提取查询弦时,代码会失败。查看代码,似乎例外是由unsafe代码抛出的,这意味着某些指针将某个地方设置为零。

我假设IIS中有一个错误,当它处理错误的请求时会触发它,例如用编码为null字符的查询串,或类似的内容。

Windows-7-SP1和Windows-Server-2008-R2-Sp1.aspx

另外,您可以尝试使用Request.PathRequest.FilePath而不是URL进行,或暗示添加try-catch并忘记它。

尝试这样做,它应该没有问题:

if (httpContext.Request != null)
{
    if (httpContext.Request.Url != null)
    {
        var url = httpContext.Request.Url;
    }
}

最新更新