对于自定义错误,我总是将以下方法放在 global.asax 中,这将激活我的错误控制器(基于此 SO 答案https://stackoverflow.com/a/5229581/426840):
protected void Application_Error()
{
var exception = Server.GetLastError();
var httpException = exception as HttpException;
// Don't execute error controller for custom error mesages when custom error is disabled
if (!HttpContext.Current.IsCustomErrorEnabled) return;
Response.Clear();
Server.ClearError();
Response.StatusCode = 500;
// Avoid IIS messing with custome errors https://stackoverflow.com/a/1719474/426840
// Also https://stackoverflow.com/a/2345742/426840 for web.config
Response.TrySkipIisCustomErrors = true;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
}
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = Response.StatusCode != 404 ? "Index" : "NotFound";
routeData.Values["exception"] = exception;
routeData.Values["logId"] = logId;
IController errorsController = new ErrorController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
错误控制器:
public class ErrorController : AuthorizedController
{
public ActionResult Index(string logId)
{
if (Request.IsAjaxRequest())
{
return new HttpStatusCodeResult(Response.StatusCode, Response.StatusDescription);
}
ViewBag.HttpStatusCode = Response.StatusCode;
ViewBag.HttpStatusMessage = Response.StatusDescription;
ViewBag.LogId = logId;
return View("Error");
}
public ActionResult NotFound(string logId)
{
if (Request.IsAjaxRequest())
{
return new HttpStatusCodeResult(Response.StatusCode, Response.StatusDescription);
}
ViewBag.HttpStatusCode = Response.StatusCode;
ViewBag.HttpStatusMessage = Response.StatusDescription;
ViewBag.LogId = logId;
return View("NotFound");
}
}
网络配置:
<customErrors mode="On" />
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<!-- Avoid IIS messing with custom errors https://stackoverflow.com/a/2345742/426840 -->
<httpErrors existingResponse="PassThrough" />
</system.webServer>
这适用于 404,但也适用于所有其他错误。