web.config / Global.asax 中的自定义错误处理不处理不存在的目录
问题是:为什么自定义错误处理不适用于不存在的路径/目录?
使用固定代码更新(感谢大家的输入):
* 更新了 web.config 和 global.asax 的代码*< /strong>
<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
页面:
Web 配置:
<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);
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从这条评论到失望先生:
谢谢,我正在使用 IIS 7 本地和 IIS 7.5 实时。当您找到材料时请告诉我。
如果您的应用程序正在配置为在经典管道模式下运行的应用程序池中运行,则不适用于 ASP.NET 的内容将不会到达 ASP.NET 运行时。即不存在的文件夹。这些将由 IIS 直接处理。
您有几个选择:
将应用程序池设置为集成管道模式。如果 IIS 的错误处理“吃掉”了 ASP.NET 中的 ASP.NET 404 和 500 状态代码,您可能还需要配置以下设置:
<前><代码><配置>;
>
<系统.web服务器>
如果应用程序在“集成管道”模式下表现不佳,但您只需关心为 404 响应显示页面,然后配置以下内容:
您需要在页面中设置
404
状态代码,否则只会返回200
。如果您使用静态页面,例如:
这将返回
404
。如果应用程序在“集成管道”模式下表现不佳,并且您绝对必须通过错误处理程序传递 404 错误,那么您可能必须手动将通配符内容映射到 ASP.NET HttpHandler,以便此类请求确实到达管道。这将是一个次优的解决方案。
From this comment to Mr. Disappointment:
Thanks, I'm using IIS 7 local and IIS 7.5 on live. Let me know when you find the material.
If your application is running in an application pool configured to run in Classic Pipeline mode then content not intended for ASP.NET won't hit the ASP.NET runtime. i.e. folders that don't exist. These will be handled directly by IIS.
You have a couple choices:
Set the application pool to Integrated Pipeline mode. You may also need to configure the following setting if IIS's error handling "eats" your ASP.NET 404 and 500 status code from ASP.NET:
If the application is not well behaved in "Integrated Pipeline" mode but you're just concerned about getting a page displayed for a 404 response then configure the following:
You'd need to set the
404
status code in the page, otherwise it'll just return a200
.If you use a static page, for example:
This will return a
404
.If the application is not well behaved in "Integrated Pipeline" mode AND you absolutely must pass 404 errors through your error handler then you may have to manually map wildcard content to the ASP.NET HttpHandler so that such requests do hit the pipeline. This would be a sub-optimal solution.
IIS 永远不会调用 ASP.NET。 IIS 处理页面请求,发现该页面不存在,并且 ASP.NET 永远不会被加载。
如果您希望无论文件是否存在都加载 ASP.NET,则需要更改 IIS 配置。您使用的是 IIS6 还是 IIS7/7.5?
ASP.NET is never being invoked by IIS. IIS handles the page request, sees that the page doesn't exist, and ASP.NET never gets loaded.
If you want ASP.NET to get loaded regardless of whether the file exists, you need to change your IIS configuration. Are you using IIS6 or 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/
You need to set up wildcard mapping so that all requests go through .Net
if your using IIS6 the following link should help you out:
http://professionalaspnet.com/archive/2007/07/27/Configure-IIS-for-Wildcard-Extensions-in-ASP.NET.aspx
Wildcard script mapping and IIS 7 integrated pipeline:
http://learn.iis.net/page.aspx/508/wildcard-script-mapping-and-iis-7-integrated-pipeline/
我找不到这方面的源材料,但我相信问题在于它正在处理自定义错误页面,而不是路径。
您的调查表明您遇到过此问题,因为:
这应该会出现正确的错误页面。以下不会:
这种重申您已经回答了自己的问题,但我会看看是否可以找到参考资料。最终,它不是页面请求,因此没有通过适当的处理程序进行 ISAPI 处理。
I can't find the source material for this but I believe the problem lies in the fact it is handling custom error pages and not paths.
You investigation suggests you came across this, inasmuch as:
This ought to hit the correct error page. The following won't:
This kind of reiterates you already answering your own question, but I'll see if I can find the reference material. Ultimately, it isn't a page request, so there is no ISAPI handling through appropriate handlers.