在MVC中处理异常的总结
无论是桌面程序还是web程序,异常处理都是必须的. 一般的处理方式是, 捕获异常,然后记录异常的详细信息到文本文件或者数据库中.
在Asp.net MVC中可以使用内建的filter——HandleError来处理程序发生的异常。接下来,来看看如何在我们的MVC项目中使用。
要让HandleErrorAttribute特性工作,需要修改我们的Web.config文件配置
- </system.web>
- ...
- <customErrors mode="On" defaultRedirect="Error.htm"/>
- </system.web>
HandleErrorAttribute 特性能够在Action, Controller, 和Global 三个级别中使用
1. 在 Action方法级别使用
在Action方法上使用,非常简单,只需要在方法头上加上HandleError特性,告诉MVC如果该Action方法出现异常,交由HandleError特性处理
- [HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")]
- public ActionResult Index(int id)
- {
- var db = new MyDataContext();
- return View("Index", db.Categories.Single(x => x.Id == id));
- }
上面例子中,当在运行Index方法的时候,如果发生数据库异常, MVC 将会显示DatabaseError
view. 所以需要在Views\Shared\下面建立一个DatabaseError.cshtml。
2. 在 Controller级别使用
同Action相似,只需要简单的将改特性放到controller类头上,告诉MVC如果该Controller中的Action方法出现异常,都交由HandleError特性处理
- [HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")]
- public class HomeController : Controller
- {
- /* Controller Actions with HandleError applied to them */
- }
3. 在Global级别上使用
我们也可以把HandleError特性注册到全局级别,使得它在全局范围中起作用。全局范围起作用的意思是,项目中的所有controller都使用HandleError处理异常。要注册global级别, 在项目的文件夹App_Start中打开 FilterConfig.cs文件找到RegisterGlobalFilters方法
默认的, ASP.NET MVC已经把HandleError特性注册成global. 这里你可以添加自定义的filter
- public static void RegisterGlobalFilters(GlobalFilterCollection filters)
- {
- filters.Add(new HandleErrorAttribute
- {
- ExceptionType = typeof(System.Data.DataException),
- View = "DatabaseError"
- });
- filters.Add(new HandleErrorAttribute()); //by default added
- }
一定要注意, 全局的filter是依照它们注册的顺序执行的。所以如果有多个filter, 要在注册其它fileter之前注册error filter
当然,你也可以在注册global filter的时候,指定它们的顺序。下面的代码是指定了顺序的,和上面的等价。
- public static void RegisterGlobalFilters(GlobalFilterCollection filters)
- {
- filters.Add(new HandleErrorAttribute(),); //by default added
- filters.Add(new HandleErrorAttribute
- {
- ExceptionType = typeof(System.Data.DataException),
- View = "DatabaseError"
- },);
- }
4. 使用MVC默认的HandleError特性的局限性
没有办法记录错误日志
它只捕获http 500错误, 但是不捕获其它类型的Http错误,比如404, 401等。
如果是在Ajax请求的情况下,返回的错误view,对于ajax访问没有任何意义。如果在Ajax请求出错的情况下,返回json对于客户端的处理就容易和友好的多。
5. 扩展HandleErrorAttribute
我们可以通过继承 HandleError
filter来实现自己的异常处理filter. 下面的filter, 实现了在出现错误的时候,记录异常日志和在Ajax请求异常的情况下,返回json对象.
- public class CustomHandleErrorAttribute : HandleErrorAttribute
- {
- public override void OnException(ExceptionContext filterContext)
- {
- if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
- {
- return;
- }
- if (new HttpException(null, filterContext.Exception).GetHttpCode() != )
- {
- return;
- }
- if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
- {
- return;
- }
- // if the request is AJAX return JSON else view.
- if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
- {
- filterContext.Result = new JsonResult
- {
- JsonRequestBehavior = JsonRequestBehavior.AllowGet,
- Data = new
- {
- error = true,
- message = filterContext.Exception.Message
- }
- };
- }
- else
- {
- var controllerName = (string)filterContext.RouteData.Values["controller"];
- var actionName = (string)filterContext.RouteData.Values["action"];
- var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
- filterContext.Result = new ViewResult
- {
- ViewName = View,
- MasterName = Master,
- ViewData = new ViewDataDictionary(model),
- TempData = filterContext.Controller.TempData
- };
- }
- // log the error by using your own method
- LogError(filterContext.Exception.Message, filterContext.Exception);
- filterContext.ExceptionHandled = true;
- filterContext.HttpContext.Response.Clear();
- filterContext.HttpContext.Response.StatusCode = ;
- filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
- }
- }
以上就是在MVC开发中,自己常用到的一些小技巧,希望对大家有帮助。
在MVC中处理异常的总结的更多相关文章
- spring MVC中的异常统一处理
1.spring MVC中定义了一个标准的异常处理类SimpleMappingExceptionResolver 该类实现了接口HandlerExceptionResolver 2.看下SimpleM ...
- spring MVC中定义异常页面
如果我们在使用Spring MVC的过程中,想自定义异常页面的话,我们可以使用DispatcherServlet来指定异常页面,具体的做法很简单: 下面看我曾经的一个项目的spring配置文件: 1 ...
- 在MVC中添加异常增加日志
MVC的结构非常棒,基本你能想到注入的地方都可以找到地方,譬如IActionFilter,IResultFilter,IAuthorizationFilter以及IExceptionFilter 以下 ...
- MVC与WebApi中的异常过滤器
一.MVC的异常过滤器 1.自定义MVC异常过滤器 创建一个类,继承HandleErrorAttribute即可,如果不需要作为特性使用直接实现IExceptionFilter接口即可, 注意,该 ...
- 解决MVC中JSON字符长度超出限制的异常
解决MVC中JSON字符长度超出限制的异常 解决方法如下: <configuration> <system.web.extensions> <scripting> ...
- MVC中使用过滤器记录异常日志
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Filte ...
- ASP.NET MVC中注册Global.asax的Application_Error事件处理全局异常
在ASP.NET MVC中,通过应用程序生命周期中的Application_Error事件可以捕获到网站引发的所有未处理异常.本文作为学习笔记,记录了使用Global.asax文件的Applicati ...
- 在ASP.NET MVC中使用Log4Net记录异常日志,出错时导向到静态页
本篇体验在ASP.NET MVC 4中使用Log4Net记录日志. 通过NuGet安装Log4Net. 需求是:当出错时导向到Error.html静态页面,Log4Net记录错误信息. 大致的思路是: ...
- 获取MVC中Controller下的Action参数异常
我现在做的一个项目有一个这样的需求, 比如有一个页面需要一个Guid类型的参数: public ActionResult Index(Guid id) { //doing something ... ...
随机推荐
- net发布的dll方法和类显示注释信息(字段说明信息)[图解]
自己发布的dll添加的另一个项目中突然没有字段说明信息了,给使用带来了很多的不便,原因是为了跨项目引用,所以导致不显示注释信息的,一下是解决这个问题的方法. 在要发布(被引用)的项目上右键 => ...
- JavaBean 的小知识点
/** * @author http://roucheng.cnblogs.com * @version 2016-05-08 */ public class Person { private Str ...
- 一文读懂UGC:互联网上的生态秘密
转载自近乎: UGC(User- Generated Content)用户原创生产内容,它是相对于PGC(Professionally-produced Content)专业生产内容的一种内容来源,简 ...
- MVC-自定义过滤器
APS.NET MVC中的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理.这时候就用到了过滤器. 自定义过滤器: 若要自定义一个过滤器,则 ...
- Lucene(01)
我的博客园博文地址:http://www.cnblogs.com/tenglongwentian/ Lucene,最新版是Lucene6.2.1,匹配的jdk版本是1.8正式版.这里用jdk7最后一版 ...
- TestNG官方文档中文版(3)-testng.xml
TestNG的官方文档的中文翻译版第3章,原文请见 http://testng.org/doc/documentation-main.html 3 - testng.xml 调用TestNG由几种不同 ...
- hibernate(四)__由表逆向创建Domain对象和对象关系映射文件
之前我们是手写Domain对象和对象关系映射文件->然后生成数据库中的Table. 现在我们反过来先在数据库中建好Table->然后用工具生成Domain对象和对象关系映射文件. 步骤: ...
- 实体类的枚举属性--原来支持枚举类型这么简单,没有EF5.0也可以
通常,我们都是在业务层和界面层使用枚举类型,这能够为我们编程带来便利,但在数据访问层,不使用枚举类型,因为很多数据库都不支持,比如我们现在用的SqlServer2008就不支持枚举类型的列,用的时候也 ...
- 值得 Web 开发人员学习的20个 jQuery 实例教程
这篇文章挑选了20个优秀的 jQuery 实例教程,这些 jQuery 教程将帮助你把你的网站提升到一个更高的水平.其中,既有网站中常用功能的的解决方案,也有极具吸引力的亮点功能的实现方法,相信通过对 ...
- react实例之todo,做一个实时响应的列表操作
react实例之todo, 做一个实时响应的列表操作 在所有的mvc框架中,最常见的例子不是hello world,而是todo,由于reactjs的简单性,在不引用flux和redux的情况下,我们 ...