MVC自定义错误页面

2021-10-04 16:19

阅读:1103

标签:bag   节点   table   oct   logs   message   sed   htm   for     MVC异常处理主要有三种方案:1.基于HandleErrorAttribute重写OnException方法;2.基于Global.apsx添加Application_Error方法;3.直接在Web.Config中配置。现基于上述思路,测试了下面三种自定义错误页面的处理方法(主要侧重于显示异常信息,便于快速找到代码中的异常来源),以便后续查阅。不足之处,还请指教! 1.直接在web.config的节点下加入,在View/Shared/Error.cshtml中写入异常信息,发生异常时会跳转到该l页面。 Web.Config @model HandleErrorInfo @{ Layout = null; } DOCTYPE html> Error Message: @Model.Exception.Message Controller: @Model.ControllerName Action: @Model.ActionName Source: @Model.Exception.Source Exception: @Model.Exception Error.html 2.新建类继承HandleErrorAttribute并重写OnException方法,将异常信息写入日志文件,并跳转到View/Shared/Error.cshtml错误页。直接将该属性作用于某控制器或者注册为全局变量以便于全局适用。 [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] public class LogExceptionAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { string controllerName = (string)filterContext.RouteData.Values["controller"]; string actionName = (string)filterContext.RouteData.Values["action"]; HandleErrorInfo info = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); Log log = new Log(); log.Write(filterContext); if (!filterContext.ExceptionHandled) { filterContext.Result = new ViewResult() { ViewName = "/Views/Shared/Error.cshtml", ViewData = new ViewDataDictionary(info) }; filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; } } } LogExceptionAttribute 错误页写入异常信息与方法1相同。 [LogException] public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { var x=1; string y="x"; ViewBag.t = x / Convert.ToInt32(y); return View(); } } 作用于单一控制器 public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); //new filters.Add(new LogExceptionAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 ); } protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } } 特性注册 3.新建继承于IController的基础控制器,重写OnException方法及写入异常日志文件,其他控制器只需要继承该基础控制器即可。与方法3的区别在于不需要注册全局筛选器取而代之的是控制器的继承。 public class BaseController : Controller { protected override void OnException(ExceptionContext filterContext) { string controllerName = (string)filterContext.RouteData.Values["controller"]; string actionName = (string)filterContext.RouteData.Values["action"]; HandleErrorInfo info = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); DateTime dt = DateTime.Now; string logPath = Server.MapPath("~/Logs/" + dt.ToString("yyyy-MM")); if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } string logFilePath = string.Format("{0}/{1}.txt", logPath, dt.ToString("yyyy-MM-dd")); StreamWriter writer = null; try { writer = new StreamWriter(logFilePath, true, Encoding.UTF8); writer.WriteLine("------------------------------------------------------------------------------"); writer.WriteLine("出错时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); writer.WriteLine("错误信息:" + filterContext.Exception.Message); writer.WriteLine("Controller:" + filterContext.Controller); writer.WriteLine("错误源:" + filterContext.Exception.Source); writer.WriteLine("堆栈信息:" + filterContext.Exception.StackTrace); writer.WriteLine("------------------------------------------------------------------------------"); } catch { } finally { if (writer != null) { writer.Close(); } } base.OnException(filterContext); filterContext.Result = new ViewResult() { ViewName = "/Views/Shared/Error.cshtml", ViewData = new ViewDataDictionary(info) }; } public ActionResult Error() { return View(); } } 基础控制器实现 public class HomeController : BaseController { // // GET: /Home/ public ActionResult Index() { var x=1; string y="x"; ViewBag.t = x / Convert.ToInt32(y); return View(); } } 控制器继承  备注:异常日志记录类 public class Log { /// /// 异常信息记录 /// /// public void Write(ExceptionContext filterContext) { DateTime dt = DateTime.Now; string logPath = HttpContext.Current.Server.MapPath("~/Logs/" + dt.ToString("yyyy-MM")); if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } string logFilePath = string.Format("{0}/{1}.txt", logPath, dt.ToString("yyyy-MM-dd")); StreamWriter writer = null; try { writer = new StreamWriter(logFilePath, true, Encoding.UTF8); writer.WriteLine("------------------------------------------------------------------------------"); writer.WriteLine("出错时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); writer.WriteLine("错误信息:" + filterContext.Exception.Message); writer.WriteLine("Controller:" + filterContext.Controller); writer.WriteLine("错误源:" + filterContext.Exception.Source); writer.WriteLine("堆栈信息:" + filterContext.Exception.StackTrace); writer.WriteLine("------------------------------------------------------------------------------"); } catch { } finally { if (writer != null) { writer.Close(); } } } } Log 4.还可以通过Global.apsx添加Application_Error方法来实现,但实验过程中不怎么喜欢这种方案,故省略。MVC自定义错误页面标签:bag   节点   table   oct   logs   message   sed   htm   for   原文地址:http://www.cnblogs.com/fuxuyang/p/7364430.html


评论


亲,登录后才可以留言!