【发布时间】:2019-03-01 21:32:09
【问题描述】:
我正在尝试使用 Global.asax 文件中的 Application_Error() 事件使用带有正确 HTTP 状态代码的自定义错误页面来处理 Asp.Net MVC 中的全局(StatusCode 500)和 http 异常。为了简单起见,实际上对于所有类型的已处理异常,我只有相同的视图错误。
现在的问题是,当处理 500 异常时,它第一次进入 Application_Error 的 else 部分,然后返回 if 部分,最后返回 404 http 异常而不是 500 异常。
当处理 500 异常时,我如何通过在 Application_Error 的 else 部分停止运行来解决这个问题?
这是我的配置: web.config
<system.web>
<customErrors mode="Off"/>
</system.web>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="400"/>
<remove statusCode="401"/>
<remove statusCode="403"/>
<remove statusCode="404"/>
<remove statusCode="500"/>
<error statusCode="400" responseMode="ExecuteURL" path="/Error"/>
<error statusCode="401" responseMode="ExecuteURL" path="/Error"/>
<error statusCode="403" responseMode="ExecuteURL" path="/Error"/>
<error statusCode="404" responseMode="ExecuteURL" path="/Error"/>
<error statusCode="500" responseMode="ExecuteURL" path="/Error"/>
</httpErrors>
</system.webServer>
方法 Application_Error():
public void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
HttpException httpException = exception as HttpException;
// Clear the response stream
HttpContext httpContext = ((HttpApplication)sender).Context;
httpContext.Response.Clear();
httpContext.ClearError();
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Error");
routeData.Values.Add("exception", exception);
if (exception.GetType() == typeof(HttpException)) //It's an Http Exception
{
routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
switch (routeData.Values["statusCode"])
{
case 400:
routeData.Values.Add("status", "400 - Bad Request");
break;
case 401:
routeData.Values.Add("status", "401 - Access Denied");
break;
case 403:
routeData.Values.Add("status", "403 - Forbidden");
break;
case 404:
routeData.Values.Add("status", "404 - Page Not Found");
break;
case 500:
default:
routeData.Values.Add("status", "500 - Internal Server Error");
break;
}
}
else
{
routeData.Values.Add("statusCode", 500);
routeData.Values.Add("status", "500 - Internal Server Error");
}
// Avoid IIS7 getting in the middle
httpContext.Response.TrySkipIisCustomErrors = true;
// Call target Controller and pass the routeData.
IController controller = new ErrorController();
controller.Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
Response.End();
// clear error on server
//Server.ClearError();
}
控制器错误控制器:
public class ErrorController : Controller
{
// GET: /Error/
public ActionResult Error(int statusCode, string status, Exception exception)
{
Response.StatusCode = statusCode;
ViewBag.StatusCode = statusCode;
ViewBag.Status = status;
return View();
}
}
【问题讨论】: