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

问题是:为什么自定义error handling不适用于不存在的路径/目录?

更新了固定代码(感谢大家为您输入):

*更新了web.config和global.asax *的代码

      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.configglobal.asax有一个自定义error handling的站点设置(设置如下所示)。 我们能够毫无问题地处理所有404和500。 错误被捕获到global.asax中的Application_Error ,记录到DB然后使用HttpContext我们设置状态代码并使用Server.Transfer()将用户移动到相应的错误页面(重定向导致302,并且伤害SEO )。

问题是用户在http://www.example.com/whatever键入时,在Firefox中显示空白页面,在IE中显示IE 404页面。 Firebug没有显示被触发的状态代码,当我调试解决方案时,没有设置的断点在global.asax被命中。 奇怪的是用户可以输入http://www.example.com/whatever/hmm.aspx并且会出现错误。 它似乎只适用于不存在的页面而不是不存在的路径/目录。

下面是我的错误的web.config代码和Application错误的global.asax代码。

我添加了* *来隐藏信息,它们中包含有效的.aspx页面:

网络配置:

           

码:

 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 = "
Error Location: " + ctx.Request.Url.ToString() + "

Error Source: " + exception.Source + "

Error Try/Catch: " + exception.InnerException + "

Error Info: " + exception.Message + "

Status Code: " + httpCode + "

Stack trace: " + 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, pattern, 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。 找到材料时请告诉我。

如果您的应用程序在配置为在Classic Pipeline模式下运行的应用程序池中运行,则不适用于ASP.NET的内容将不会访问ASP.NET运行时。 即不存在的文件夹。 这些将由IIS直接处理。

你有几个选择:

  1. 将应用程序池设置为Integrated Pipeline模式。 如果IIS的error handling从ASP.NET“”占用“ASP.NET 404和500状态代码,则可能还需要配置以下设置:

          
  2. 如果应用程序在“集成管道”模式下表现不佳,但您只关心为404响应显示页面,请配置以下内容:

           

    您需要在页面中设置404状态代码,否则它将返回200

    如果您使用静态页面,例如:

      

    这将返回404

  3. 如果应用程序在“集成管道”模式下表现不佳并且您必须通过error handling程序传递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。