MVC自定义错误页面
MVC异常处理主要有三种方案:1.基于HandleErrorAttribute重写OnException方法;2.基于Global.apsx添加Application_Error方法;3.直接在Web.Config中配置。现基于上述思路,测试了下面三种自定义错误页面的处理方法(主要侧重于显示异常信息,便于快速找到代码中的异常来源),以便后续查阅。不足之处,还请指教!
1.直接在web.config的<system.web>节点下加入<customErrors mode="On" />,在View/Shared/Error.cshtml中写入异常信息,发生异常时会跳转到该l页面。
<system.web>
<customErrors mode="On" />
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="" />
</authentication>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
</namespaces>
</pages>
</system.web>
Web.Config
@model HandleErrorInfo
@{
Layout = null;
} <!DOCTYPE html>
<html>
<head>
<title>Error</title>
</head>
<body>
<p>Message: @Model.Exception.Message</p>
<p>Controller: @Model.ControllerName</p>
<p>Action: @Model.ActionName</p>
<p>Source: @Model.Exception.Source</p>
<p>Exception: @Model.Exception</p>
</body>
</html>
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<HandleErrorInfo>(info)
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
}
LogExceptionAttribute
错误页写入异常信息与方法1相同。
[LogException]
public class HomeController : Controller
{
//
// GET: /Home/ public ActionResult Index()
{
var x=;
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<HandleErrorInfo>(info)
};
} public ActionResult Error()
{
return View();
}
}
基础控制器实现
public class HomeController : BaseController
{
//
// GET: /Home/ public ActionResult Index()
{
var x=;
string y="x";
ViewBag.t = x / Convert.ToInt32(y);
return View();
}
}
控制器继承
备注:异常日志记录类
public class Log
{
/// <summary>
/// 异常信息记录
/// </summary>
/// <param name="filterContext"></param>
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自定义错误页面的更多相关文章
- ASP.NET MVC 自定义错误页面心得
自定义错误页面的目的,就是为了能让程序在出现错误/异常的时候,能够有较好的显示体验. 所以,首先要先了解,我们可以在哪里捕获异常. 当程序发生错误的时候,我们可以在两个地方捕获: Global里面的A ...
- MVC 自定义 错误页面
很多时候,我们需要自定义错误页面,用来当发生异常后引导用户进入一个比较友好的错误页面. 在这里,我归结一下我常用的2个方案 1 通过Global.asax 文件来处理异常信息(这个不管是 MVC ...
- 在ASP.NET MVC自定义错误页面
异常处理跳转页面 第一步,在项目的Web.config文件中找到节点<system.web> 在此节点下添加配置(Error为定义的控制器也可以多添加些error标签用于区分不同的错误) ...
- Asp.net MVC 自定义错误页面以及return HttpNotFound遇到的问题
今天在处理mvc 项目404和500页面时,发现我以前比较喜欢用的Return HttpNotFound()没有跳转到我在webconfig中配置的自定义404页面,而且也不会去执行Global中的A ...
- Spring MVC自定义错误页面
在web.xml中添加: <error-page(其他属性404...省略咯)> <location>/error</location> </error-pa ...
- .net mvc 自定义错误页面
1.Global.asax.cs中,加入如下代码 protected void Application_Error(Object sender, EventArgs e) { Exception ex ...
- ASP.NETMVC自定义错误页面真的简单吗?
Note:文章前半部分翻译自 http://benfoster.io/blog/aspnet-mvc-custom-error-pages ,着急的可直接看总结~ 如果你在设置asp.net mvc自 ...
- 自定义错误页面mvc用法
原谅我这个新手,对大神们来说这么简单的问题,竟折腾了我一个上午,仅此文章做个记录,供以后备用. 自定义错误页面(custom error pages)在asp.net webform里的配置请看htt ...
- ASP.NET Core中显示自定义错误页面
在 ASP.NET Core 中,默认情况下当发生500或404错误时,只返回http状态码,不返回任何内容,页面一片空白. 如果在 Startup.cs 的 Configure() 中加上 app. ...
随机推荐
- php中mysql_fetch_row() 和mysql_fetch_array之间有什么区别
mysql_fetch_row是从结果集取出1行数组,作为枚举 mysql_fetch_array是从结果集取出一行数组作为关联数组,或数字数组,两者兼得eg:$sql="select ab ...
- 【2018 “百度之星”程序设计大赛 - 初赛(B)-1004】p1m2(迷之二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6383 题目就是让你求一个整数数组,在进行任意元素 + 1. - 2 操作后,请问在所有可能达到的稳定数 ...
- ElementTree之Xml文档处理
ElementTree: 表示整个XML层级结构 Element: 表示树形结构中所有的父节点 SubElement: 表示树形结构中所有的子节点 有些节点既是父节点,又是子节点 下面来看下这两个类的 ...
- 怎样安装 OpenJDK 8 in Ubuntu 14.04 & 12.04 LTS
OpenJDK Java 8 has been made into official Ubuntu repositories for 14.10 Utopic and higher. For Ubun ...
- asp.net设置gridview页码显示遇到的问题
问题:分页部分显示的页码撑开占满整个表格底部 解决方法: 1.通过浏览器察看源,发现是分页部分的table样式受到整个页面的table设置的样式的影响,分页是一个tr里面的td里面的table 2.设 ...
- 访问IO设备
http://blog.csdn.net/goodluckwhh/article/details/16986871 内存屏障主要解决的问题是编译器的优化和CPU的乱序执行.编译器在优化的时候,生成的汇 ...
- Intellij IDEA创建包(package)问题解决方案
问题 在使用IDEA创建包时会出现这样一种场景,就是当一个空包很长时,比如com.secbro.drools.model.这个时候如果你想给drools或model创建同级的包,你会发现,默认创建的包 ...
- 安全性测试AppScan工具使用实战20150920
Appscan是做安全性测试的一款工具,网上资料比较少,项目需要做安全性测试,用它做了web的扫描,可以发现一些问题,并且有原因分析和修复建议,感觉还不错,现在实战 1.打开工具,点击[文件]下的[新 ...
- 音乐随想——斯美塔那—G小调钢琴协奏曲
乐源 Music -> Piano Trio -> Smetana:Piano Trioin G minor Op.15 总结 每一乐章都会有一段美到极致的主旋律. 第一乐章 起头即有凄凉 ...
- 类中的__slots__方法与__dict__方法相排斥
类的 __slots__ 列表 作用: 限定一个类创建的实例只能有固定的属性(实例变量) 不允许对象添加列表以外的属性(实例变量) 防止用户因错写属性的名称而发生程序错误 说明: 1. __slots ...