我花了一天时间浏览了十几个网站,博客和SO答案,他们都声称在ASP.NET MVC中提供了“正确”的方式来实现自定义错误处理。
他们彼此之间并不一致,而且他们中的大多数似乎都不起作用。
我想要的是什么:
而且,我希望这是规范的答案。不只是“这就是我的工作”,而是“这是微软开发人员打算并期望完成的工作”。
有什么想法吗?
答案 0 :(得分:4)
我不确定这是否是最好的方式,但它适用于我及其友好的seo: web.config
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
</httpErrors>
</system.webServer>
您也可以定义子状态代码:
<error statusCode="404" subStatusCode="2" responseMode="ExecuteURL" path="/Error/NotFound" />
这就是我的错误控制器的样子:
public class ErrorController : Controller
{
//
// GET: /Error/
public ActionResult NotFound()
{
// you have to set your error codes manually
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
}
答案 1 :(得分:4)
以下解决方案满足您的大部分要求,但:
创建一个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");
}
}
添加一条路线以捕获路线配置末尾的所有网址 - 这会捕获匹配现有路线尚未捕获的所有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));
}
}
摘要:
答案 2 :(得分:2)
有两种类型的错误处理。
对于页面级错误,您既可以使用web.config,也可以创建基本控制器并覆盖OnException事件。
protected override void OnException(ExceptionContext filterContext) { ... }
对于应用程序级错误,您可以使用global.asax Application_Error事件
void Application_Error(object sender, EventArgs e) { ... }
您也可以查看以下链接:https://www.simple-talk.com/dotnet/asp.net/handling-errors-effectively-in-asp.net-mvc/
答案 3 :(得分:0)
单向可能是:
ErrorFilter:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
HandleErrorAttribute attribute = new HandleErrorAttribute();
filters.Add(attribute);
}
覆盖控制器的OnException方法
protected override void OnException(ExceptionContext filterContext)
{
EventLog.WriteEntry("YourProjectEventName", filterContext.Exception.ToString(), EventLogEntryType.Error);
base.OnException(filterContext);
}
参考链接:
http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc
http://www.codeproject.com/Articles/422572/Exception-Handling-in-ASP-NET-MVC
希望这有帮助。