问题是:为什么自定义错误处理对不存在的路径/目录不起作用?
更新了固定代码(感谢大家的输入):
* 更新了 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)。
问题是当用户键入 http://www.example.com/whatever
时,Firefox 中显示空白页面,而 IE 中显示 IE 404 页面。 Firebug 显示没有状态代码被触发,当我调试解决方案时,我在 global.asax
中设置的断点没有命中。奇怪的是,用户可以输入 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, 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。找到资料后请告诉我。
如果您的应用程序在配置为以经典管道模式运行的应用程序池中运行,那么不适用于 ASP.NET 的内容将不会命中 ASP.NET 运行时。即不存在的文件夹。这些将由 IIS 直接处理。
你有几个选择:
将应用程序池设置为集成管道模式。如果 IIS 的错误处理“吞噬”了 ASP.NET 中的 ASP.NET 404 和 500 状态代码,您可能还需要配置以下设置:
<configuration> <system.webServer> <httpErrors existingResponse="PassThrough" /> </system.webServer> </configuration>
如果应用程序在“集成管道”模式下表现不佳,但您只关心为 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
。如果应用程序在“集成管道”模式下表现不佳,并且您绝对必须通过错误处理程序传递 404 错误,那么您可能必须手动将通配符内容映射到 ASP.NET HttpHandler,以便此类请求能够执行打管道。这将是一个次优的解决方案。
关于c# - web.config/Global.asax 中的自定义错误处理不处理不存在的目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5664689/