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. ...
随机推荐
- VB与C#的区别(转载)
由于工作原因要熟悉这两门编程语言.网上找的. VB.NET Program Structure C# Imports System Namespace Hello Clas ...
- ZOJ 1609 Equivalence(状压+dfs减枝)
ZOJ Problem Set - 1609 Equivalence Time Limit: 5 Seconds Memory Limit: 32768 KB When learning m ...
- Java基础学习-内部类
/*内部类: 成员内部类 局部内部类 匿名内部类*/ package insideclass; /*成员内部类: * 在类的成员位置,和成员变量,成员方法的位置是一样的. * 内部类可以直接访问为外部 ...
- .net的session详解
http://blog.csdn.net/justin_wkf/article/details/5746914#comments
- CMD命令提示符下选中文字即可以复制和SecureCRT一样
用过 SecureCRT 的都会觉得复制粘贴很方便.只要选中相应文字,会自动复制.然后点鼠标右键就可以粘贴,非常方便. 但是在windows系统下的CMD里面,每次都要点鼠标右键→标记,再选中相应文字 ...
- Shell 命令行实现将一个站点页面全部下载到本地并替换其中链接的脚本
Shell 命令行实现将一个站点页面全部下载到本地并替换其中链接的脚本 不知道为什么,我总想用 Shell 脚本来实现把一个站点内容给下载下来.但是下载什么站点我确不知道.今天尝试了一下利用 curl ...
- flowable EngineConfiguration的作用和继承关系(1)
EngineConfiguration 是flowable引擎的核心部件. 在 flowable 中,实现引擎配置的顶层类是 AbstractEngineConfiguration 这是一个抽象类. ...
- IOS开发 多线程编程 - NSOperation
一.NSOperation 1.简介 NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作. NSOperation本身是抽象基类,因此必须使用 ...
- caffe 卷积层的运算
贾清扬寻找快速算法之路:https://github.com/Yangqing/caffe/wiki/Convolution-in-Caffe:-a-memo 卷积运算图文并茂:http://www. ...
- JS修改标签中的文本且不影响其中标签
/********************************************************************* * JS修改标签中的文本且不影响其中标签 * 说明: * ...