web.config / Global.asax中的自定义错误处理不处理不存在的目录

问题描述

|| 问题是:为什么自定义错误处理不适用于不存在的路径/目录? 更新了固定代码(感谢大家输入): *更新了web.config和global.asax的代码*
<httpErrors errorMode=\"Custom\">
        <remove statusCode=\"500\" subStatusCode=\"-1\" />
        <remove statusCode=\"404\" subStatusCode=\"-1\" />
        <error statusCode=\"404\" subStatusCode=\"-1\" prefixLanguageFilePath=\"\" path=\"/*****.aspx\" responseMode=\"ExecuteURL\" />
        <error statusCode=\"500\" subStatusCode=\"-1\"  prefixLanguageFilePath=\"\" path=\"/*****.aspx\"  responseMode=\"ExecuteURL\"/>
    </httpErrors>

    added this to the global.asax to stop IIS from handling my 500 errors
    after @Kev\'s suggestions IIS handled my 500\'s these lines fixed that
    HttpApplication myApplication = new HttpApplication();
    myApplication.Response.TrySkipIisCustomErrors = true;
我们有一个站点设置,带有
web.config
global.asax
中的自定义错误处理(设置如下所示)。我们能够处理所有404和500。错误会被捕获到
global.asax
中的
Application_Error
中,并记录到数据库中,然后使用
HttpContext
来设置状态代码并使用
Server.Transfer()
用户移动到相应的错误页面重定向会导致302,并损害SEO)。 问题是当用户键入“ 7”时,Firefox中显示一个空白页面,而在IE中则显示IE 404页面。 Firebug不会显示任何状态代码,并且在调试解决方案时,不会在ѭ2中命中设置的断点。奇怪的是,用户可以输入
http://www.example.com/whatever/hmm.aspx
,并且会出现错误。看来,它只能在不存在的页面上工作,而不能在不存在的路径/目录上工作。 以下是我的错误代码
web.config
和应用程序错误代码
global.asax
。 我添加了**以隐藏信息,其中包含有效的
.aspx
页面: 网页配置:
<customErrors defaultRedirect=\"~/******.aspx\" mode=\"On\" 
              redirectMode=\"ResponseRewrite\">
    <error statusCode=\"500\" redirect=\"~/*****.aspx\" />
    <error statusCode=\"404\" redirect=\"~/*****.aspx\" />
</customErrors>

    <httpErrors errorMode=\"Custom\">
        <remove statusCode=\"500\" subStatusCode=\"-1\" />
        <remove statusCode=\"404\" subStatusCode=\"-1\" />
        <error statusCode=\"404\" subStatusCode=\"-1\" prefixLanguageFilePath=\"\" path=\"/*****.aspx\" responseMode=\"ExecuteURL\" />
        <error statusCode=\"500\" subStatusCode=\"-1\"  prefixLanguageFilePath=\"\" path=\"/*****.aspx\"  responseMode=\"ExecuteURL\"/>
    </httpErrors>
码:
protected void Application_Error(Object sender,EventArgs e)
{
    // At this point we have information about the error
    HttpContext ctx = HttpContext.Current;

    // set the exception to the Context 
    Exception exception = ctx.Server.GetLastError();

    // get the status code of the Error
    int httpCode = ((HttpException)exception).GetHttpCode();

    // get the IP Address
    String strHostName = string.Empty;
    String ipAddress_s = string.Empty;
    strHostName = System.Net.Dns.GetHostName();

    System.Net.IPHostEntry ipEntry = System.Net.Dns.GetHostByName(strHostName);
    System.Net.IPAddress[] addr = ipEntry.AddressList;

    for (int i = 0; i < addr.Length; i++)
    {
        ipAddress_s += \"IP Address {\" + (i + 1) + \"} \" + 
                            addr[i].ToString() + Environment.NewLine;
    }

    // setup the error info one for user display and one for the DB Insert
    string errorInfo =
       \"<br /><b>Error Location:</b> \" + ctx.Request.Url.ToString() +
       \"<br /><br /><b>Error Source:</b> \" + exception.source +
       \"<br /><br /><b>Error Try/Catch:</b> \" + exception.InnerException +
       \"<br /><br /><b>Error Info:</b> \" + exception.Message +
       \"<br /><br /><b>Status Code:</b> \" + httpCode +
       \"<br /><br /><b>Stack trace:</b> \" + exception.StackTrace;
    string errorInfoDB =
       \"||Error Location: \" + ctx.Request.Url.ToString() +
       \"||Error Source: \" + exception.source +
       \"||Error Try/Catch: \" + exception.InnerException +
       \"||Error Info: \" + exception.Message +
       \"||HttpErrorCode: \" + httpCode +
       \"||Stack trace: \" + exception.StackTrace +
       \"||IP Address: \" + ipAddress_s;

    // clean the input befor you put it in the DB
    char quote = (char)34;
    char filler = (char)124;
    char tick = (char)39;
    char greaterThan = (char)60;
    char lessthan = (char)62;
    errorInfo = errorInfo.Replace(quote,filler);
    errorInfo = errorInfo.Replace(tick,filler);
    errorInfo = errorInfo.Replace(greaterThan,filler);
    errorInfo = errorInfo.Replace(lessthan,filler);

    errorInfoDB = errorInfoDB.Replace(quote,filler);
    errorInfoDB = errorInfoDB.Replace(tick,filler);
    errorInfoDB = errorInfoDB.Replace(greaterThan,filler);
    errorInfoDB = errorInfoDB.Replace(lessthan,filler);

    string pattern = string.Empty;
    string replacement = \"squeel\";
    pattern = \"/cookie|SELECT|UPDATE|INSERT|INTO|DELETE|FROM|NOT IN|WHERE|TABLE|DROP|script*/ig\";
    errorInfoDB = Regex.Replace(errorInfoDB,pattern,replacement);

    pattern = \"/cookie|select|update|insert|into|delete|from|not in|where|table|drop|script*/ig\";
    errorInfoDB = Regex.Replace(errorInfoDB,replacement);


    if (httpCode == 404)
    {
        InSert_To_DB_Class(*****,*****,errorInfoDB);
    }
    else
    {
        InSert_To_DB_Class(*****,errorInfoDB);
    }

    // set the error info to the session variable to display to the allowed users
    Application[\"AppError\"] = errorInfo;

    // clear the error Now that is has been stored to a session
    ctx.Server.ClearError();
    ctx.Response.ClearHeaders();
    // set the status code so we can return it for SEO
    ctx.Response.StatusCode = httpCode;
    ctx.Response.TrySkipIisCustomErrors = true;
    HttpApplication myApplication = new HttpApplication();
    myApplication.Response.TrySkipIisCustomErrors = true;
    try
    {
        if (ctx.Request.RawUrl.Contains(\"/*****\"))
        {
            // redirect to the error page
            ctx.Server.Transfer(\"~/*****.aspx\",false);
        }
        else if(ctx.Request.RawUrl.Contains(\"/*****\"))
        {
            ctx.Server.Transfer(\"~/*****/*****.aspx\",false);
        }
        else
        {
            // check the httpCode
            if (httpCode == 404)
            {
                // set the page name they were trying to find to a session variable
                // this will be cleared in the ****** page
                Application[\"404_page\"] = exception.Message; 
                // redirect to the 404 page
                ctx.Server.Transfer(\"~/*****\",false);
            }
            else
            {
                // redirect to the error page
                ctx.Server.Transfer(\"~/*****\",false);
            }
        }
    }
}
    

解决方法

从此评论到失望先生: 谢谢,我正在现场使用IIS 7和IIS 7.5。找到材料时让我知道。 如果您的应用程序在配置为以经典管道模式运行的应用程序池中运行,则非ASP.NET的内容将不会到达ASP.NET运行时。即不存在的文件夹。这些将由IIS直接处理。 您有两种选择: 将应用程序池设置为集成管道模式。如果IIS的错误处理“吞噬”了您的ASP.NET 404和来自ASP.NET的500状态代码,则可能还需要配置以下设置:
<configuration>
  <system.webServer>
    <httpErrors existingResponse=\"PassThrough\" />
  </system.webServer>
</configuration>
如果应用程序在\“ Integrated Pipeline \”模式下表现不佳,但是您只担心要显示针对404响应的页面,请配置以下内容:
<system.webServer>
  <httpErrors>
    <remove statusCode=\"404\" subStatusCode=\"-1\" />
    <error statusCode=\"404\" prefixLanguageFilePath=\"\" 
           path=\"/404.aspx\" responseMode=\"ExecuteURL\" />
  </httpErrors>
</system.webServer>
您需要在页面中设置
404
状态代码,否则它将仅返回
200
。 如果使用静态页面,例如:
<error statusCode=\"404\" prefixLanguageFilePath=\"\" 
       path=\"404.html\" responseMode=\"File\" />
这将返回
404
。 如果应用程序在\“ Integrated Pipeline \”模式下表现不佳,并且您绝对必须通过错误处理程序传递404错误,则可能必须手动将通配符内容映射到ASP.NET HttpHandler,以便此类请求能够正常执行。这将是次佳的解决方案。     ,IIS永远不会调用ASP.NET。 IIS处理页面请求,发现该页面不存在,并且ASP.NET从未加载。 如果希望无论文件是否存在都加载ASP.NET,则需要更改IIS配置。您使用的是IIS6还是IIS7 / 7.5?     ,您需要设置通配符映射,以便所有请求都通过.Net 如果您使用IIS6,则以下链接将为您提供帮助: http://professionalaspnet.com/archive/2007/07/27/Configure-IIS-for-Wildcard-Extensions-in-ASP.NET.aspx 通配符脚本映射和IIS 7集成管道: http://learn.iis.net/page.aspx/508/wildcard-script-mapping-and-iis-7-integrated-pipeline/     ,我找不到用于此目的的源材料,但我相信问题在于它正在处理自定义错误页面而非路径。 您的调查表明您遇到了这种情况,因为:
www.mysite.com/nonexistingpath/nonexistingpage.aspx
这应该点击正确的错误页面。以下内容不会:
www.mysite.com/nonexistingpath/
重申您已经回答了自己的问题,但是我看看是否可以找到参考资料。最终,它不是页面请求,因此没有通过适当的处理程序进行ISAPI处理。