我的目标是在应用程序中创建一个错误处理来处理所有托管错误,而不仅仅是与 MVC 相关。所以我没有使用 HandleErrorAttribute 模式,因为它仅适用于 MVC 错误,而不适用于其他托管错误。
在我的 Global.asax 中,我有:
protected void Application_Error()
{
string displayError = ConfigurationManager.AppSettings["DisplayError"];
NameValueCollection serverVariables;
int loop1, loop2;
StringBuilder serverVariableKeys = new StringBuilder();
Exception exception = Server.GetLastError();
HttpException httpException = exception as HttpException;
if (HttpContext.Current != null)
{
// loop through and get server vars
}
if (exception != null)
// Log Error
// Redirect to Error page if set to basic mode
if (!string.IsNullOrWhiteSpace(displayError) && displayError.ToLower() == "basic")
{
Response.Clear();
Server.ClearError(); // needed for redirect to work
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode)
{
case 403:
routeData.Values["action"] = "Http403";
break;
case 404:
routeData.Values["action"] = "Http404";
break;
}
}
IController errorsController = new Controllers.ErrorController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
}
我有一个that ErrorController
hasGeneral
和Actions。我有对应于每个动作的视图。Http403
Http404
在我的 web.config 中,我有:
<system.web>
<!-- removed bits to reduce space -->
<customErrors mode="On" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules >
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
<remove name="Session"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition=""/>
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<httpErrors errorMode="Detailed" />
</system.webServer>
这适用于与托管代码相关的许多场景,但是当 IIS 接管时,例如错误的静态文件调用 (example.com/BadFileName.gif),它将从 IIS 返回一个错误,该错误会泄露服务器详细信息,例如本地文件路径。这是因为 web.config 中的以下行:
<httpErrors errorMode="Detailed" />
但是,当我将 errorMode 设置为其他值(例如自定义)或仅删除该行时,我的自定义错误处理将停止运行,并且会为包括托管代码错误在内的所有内容返回默认的 IIS 错误消息。
我已经尝试了很多方法来让自定义错误在没有此设置的情况下正常工作,但没有任何运气,包括:
- 设置
CustomError
为mode="Off"
- 在下定义错误节点
customError
以重定向到我的控制器 - 在下定义错误节点
httpErrors
以重定向到我的控制器
当我逐步调试时,我可以看到对控制器的调用,但最终 IIS 发送了响应。错误日志确实被正确调用了 Application_Error,因此代码确实让应用程序将其处理到某个点。
申请详情:
- ASP.NET MVC 4.0
- 托管在 IIS 7.5(Azure 网站预览版)上
有没有办法不使用<httpErrors errorMode="Detailed" />
并使这项工作?