http://2sharings.com/2015/asp-net-mvc-5-custom-404-500-error-hanlde
https://blog.csdn.net/yhyhyhy/article/details/51003683
ASP.NET MVC 5的开发中,服务器的各种错误[如:401(登录授权验证),403(禁止访问),404(访问页面不存在),500(服务器内部错误)等]处理是必需考虑并解决的一个问题,如果不处理这些错误或者使用默认的错误页面,那么用于用户体验来说就不是很友好了。严重的甚至可以暴露程序以及服务器的各种信息,给黑客以可乘之机。 网上关于ASP.NET MVC 5的服务器错误处理拦截问题没有太全的总结和整理。今天用一个简单实例来总结整理一下这方面的处理技巧。 首先是404页面的处理,本示例利用Global.asax文件的Application_Error()方法来拦截,使用Server.GetLastError()方法获取到服务器的最后一次错误作为HttpException,再根据httpException的GetHttpCode()方法获取到的http状态码来处理404的页面不存在的问题,Global.asax代码如下:
protected void Application_Error(object sender, EventArgs e) { Exception exception = Server.GetLastError(); HttpException httpException = exception as HttpException; RouteData routeData = new RouteData(); routeData.Values.Add("controller", "Error"); switch (httpException.GetHttpCode()) { case 404: routeData.Values.Add("action", "HttpError404"); break; } Response.Clear(); Server.ClearError(); Response.TrySkipIisCustomErrors = true; IController errorController = new ErrorController(); errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); //Response.RedirectToRoute(new { controller = "Error", action = "HttpError404" }); }
以上的404错误处理是直接将事先制作好的HttpError404.cshtml视图信息显示在请求的页面,如: 其次是401(未授权)页面的拦截处理,本示例是创建了一个名为AuthorizeCheckAttribute属性类,此类继承至AuthorizeAttribute类,在AuthorizeCheckAttribute类中,重写了HandleUnauthorizedRequest方法,我们中此方法中来处理所有需要授权但未授权访问的请求,然后再在需要授权访问的控制器或者Action上使用AuthorizeCheck属性,AuthorizeCheckAttribute属性类的代码如下:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { base.HandleUnauthorizedRequest(filterContext); if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { try { filterContext.Controller.TempData.Add("Alert", new Alert { Type = AlertType.Error, Message = "请登录后访问" }); } catch { } filterContext.Result = new ViewResult { TempData = filterContext.Controller.TempData, ViewName = "~/Views/Error/HttpError401.cshtml" }; //new RedirectResult("~/error/httperror401"); } }
需要授权访问的Action如下:
[AuthorizeCheck] public ActionResult UnAuthorize() { return View(); }
这样,如果在未登录授权的情况下访问UnAuthorize这个Action,那么就会被拦截到。我们可以在拦截器里任意处理错误信息了,比如把错误记录到日志等。 最后,我们来处理的服务器的500内部错误。首先创建一个名为CustomHandleErrorAttribute的自定义错误处理属性类,此类继承至HandleErrorAttribute类,在CustomHandleErrorAttribute类中重写OnException方法,代码如下:
public override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); Exception exception = filterContext.Exception; try { //TODO:写错误日志 filterContext.Controller.TempData.Add("Alert", new Alert { Type = AlertType.Error, Message = exception.ToString() }); } catch { } filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; //filterContext.Result = new RedirectResult("~/error/httperror500"); filterContext.Result = new ViewResult { TempData=filterContext.Controller.TempData, ViewName = "~/Views/Error/HttpError500.cshtml" }; //var Result = this.View("Error", new HandleErrorInfo(exception, //filterContext.RouteData.Values["controller"].ToString(), //filterContext.RouteData.Values["action"].ToString())); //filterContext.Result = Result; }
以上代码中,我们使用了filterContext.Result属性来设置拦截到内部错误后的返回视图名字和返回的信息。当然,在OnException这个重写方法中,我们还可以处理日志等操作,根据自已需要来实现就行。写好这个类后,我们再修改FilterConfig类的RegisterGlobalFilters的方法,如下:
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomHandleErrorAttribute()); } }
当然,我们事先已经在Global.asax文件中注册了全局拦截配置了,Application_Start代码如下:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
好了,以上就是关于ASP.NET MVC 5中处理各种服务器错误的自定义页面的操作,希望对你有所帮助。 如果你有更好的实现方法,也欢迎留言交流。 最后,我把本实例的代码提供如下,。