【发布时间】:2014-09-15 09:18:16
【问题描述】:
如何显示自定义错误页面,当发生 Http 错误而不更改 url。
当发生 Http 错误时,如何在不路由到另一个 Url 的情况下显示客户自定义错误页面。
【问题讨论】:
如何显示自定义错误页面,当发生 Http 错误而不更改 url。
当发生 Http 错误时,如何在不路由到另一个 Url 的情况下显示客户自定义错误页面。
【问题讨论】:
以下方法不会使用重定向 - 它会返回您的自定义错误 + 正确的 httpstatus 代码作为对客户端的即时响应,方法是在 application_error 方法中捕获错误,然后选择在同一响应中返回的内容,删除需要重定向。
创建一个 ErrorController - 这允许您定制您的最终用户错误页面和状态代码。:
[AllowAnonymous]
public class ErrorController : Controller
{
public ActionResult PageNotFound()
{
Response.StatusCode = 404;
return View();
}
public ActionResult ServerError()
{
Response.StatusCode = 500;
return View();
}
public ActionResult UnauthorisedRequest()
{
Response.StatusCode = 403;
return View();
}
//Any other errors you want to specifically handle here.
public ActionResult CatchAllUrls()
{
//throwing an exception here pushes the error through the Application_Error method for centralised handling/logging
throw new HttpException(404, "The requested url " + Request.Url.ToString() + " was not found");
}
}
添加一个路由以捕获所有 url 到您的路由配置的末尾 - 这将捕获所有通过匹配现有路由尚未捕获的 404:
routes.MapRoute("CatchAllUrls", "{*url}", new { controller = "Error", action = "CatchAllUrls" });
在您的 global.asax 中:
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
//Error logging omitted
HttpException httpException = exception as HttpException;
RouteData routeData = new RouteData();
IController errorController = new Controllers.ErrorController();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("area", "");
routeData.Values.Add("ex", exception);
if (httpException != null)
{
//this is a basic exampe of how you can choose to handle your errors based on http status codes.
switch (httpException.GetHttpCode())
{
case 404:
Response.Clear();
// page not found
routeData.Values.Add("action", "PageNotFound");
Server.ClearError();
// Call the controller with the route
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
break;
case 500:
// server error
routeData.Values.Add("action", "ServerError");
Server.ClearError();
// Call the controller with the route
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
break;
case 403:
// server error
routeData.Values.Add("action", "UnauthorisedRequest");
Server.ClearError();
// Call the controller with the route
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
break;
//add cases for other http errors you want to handle, otherwise HTTP500 will be returned as the default.
default:
// server error
routeData.Values.Add("action", "ServerError");
Server.ClearError();
// Call the controller with the route
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
break;
}
}
//All other exceptions should result in a 500 error as they are issues with unhandled exceptions in the code
else
{
routeData.Values.Add("action", "ServerError");
Server.ClearError();
// Call the controller with the route
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
}
【讨论】:
在web.config中添加<customErrors>标签,帮助你在系统找不到请求的url(状态码404)时重定向到Error控制器的NotFound动作方法,并重定向到错误控制器的ServerError动作方法如果系统触发内部服务器错误(状态码 500)
<!--<Redirect to error page>-->
<customErrors mode="On" defaultRedirect="~/Error/ServerError">
<error redirect="~/Error/NotFound" statusCode="404" />
</customErrors>
<!--</Redirect to error page>-->
您必须创建一个包含 ServerError 和 NotFound 操作方法的错误控制器,该操作方法呈现相关视图以向用户显示正确的消息。
public class ErrorController : Controller
{
public ActionResult NotFound()
{
return View();
}
public ActionResult Error()
{
return View();
}
}
为了在发生自定义错误时保持相同的 url,您需要安装 Magical Unicorn Mvc Error Toolkit 2.2.2 nuget 包。
您可以按照以下步骤进行操作:
Tools 菜单并选择Nuget Package Manager
Package Manager Console
PM> Install-Package MagicalUnicorn.MvcErrorToolkit
你可以visit here for more info关于nuget包
它将根据您的要求安装 nuget 包。
【讨论】: