创建一个 ErrorController - 这允许您定制您的最终用户错误页面和状态代码。每个操作结果都接受一个异常,您可以在 global.asax 中的 application_error 方法中将其添加到您的路由数据中。它不必是异常对象,它可以是任何你喜欢的对象 - 只需将它添加到 application_error 中的 routedata 即可。
[AllowAnonymous]
public class ErrorController : Controller
{
public ActionResult PageNotFound(Exception ex)
{
Response.StatusCode = 404;
return View("Error", ex);
}
public ActionResult ServerError(Exception ex)
{
Response.StatusCode = 500;
return View("Error", ex);
}
public ActionResult UnauthorisedRequest(Exception ex)
{
Response.StatusCode = 403;
return View("Error", ex);
}
//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");
}
}
您的错误视图:
@model Exception
@{
ViewBag.Title = "Error";
}
<h2>Error</h2>
@Model.Message
添加一个路由以捕获所有 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 example 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));
}
}
然后当你抛出
throw new HttpException(404, "Invoice 5 does not exist");
您的消息将被传递并显示给用户。此时您可以指定要使用哪个状态码,并在 application_error 中扩展 switch 语句。