我正在尝试使用Global.asax文件中的Application_Error()事件在Asp.Net MVC中使用自定义错误页面和正确的HTTP状态代码来处理global(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();
}
Controller ErrorController:
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();
}
}
答案 0 :(得分:0)
其背后的原因是,应用程序引发的Exception
的类型并不总是HttpException
。可能是SQLException, SystemException, IndexOutOfRangeException
等。状态代码始终仅与HttpExceptions
关联。这就是为什么您的代码首先进入else
部分,然后进入if
部分的原因。
尽管它不应再次出现在if
部分,但是如果即将出现,则必须检查要重定向的页面是否没有引发其他异常。
我还建议您从代码中删除最后一个参数,因为Exception是一种复杂类型,并且我们通常不会在Get请求中传递复杂类型。
转换
public ActionResult Error(int statusCode, string status, Exception exception)
到
public ActionResult Error(int statusCode, string status)