摘要

在asp.net mvc中除了使用try...catch/finally来处理异常外,它提供了一种通过在Controller或者Action上添加特性的方式来处理异常。

HandleErrorAttribute

首先看一下该特性的定义

using System;

namespace System.Web.Mvc
{
// 摘要:
// 表示一个特性,该特性用于处理由操作方法引发的异常。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
{
// 摘要:
// 初始化 System.Web.Mvc.HandleErrorAttribute 类的新实例。
public HandleErrorAttribute(); // 摘要:
// 获取或设置异常的类型。
//
// 返回结果:
// 异常的类型。
public Type ExceptionType { get; set; }
//
// 摘要:
// 获取或设置用于显示异常信息的母版视图。
//
// 返回结果:
// 母版视图。
public string Master { get; set; }
//
// 摘要:
// 获取此特性的唯一标识符。
//
// 返回结果:
// 此特性的唯一标识符。
public override object TypeId { get; }
//
// 摘要:
// 获取或设置用于显示异常信息的页视图。
//
// 返回结果:
// 页视图。
public string View { get; set; } // 摘要:
// 在发生异常时调用。
//
// 参数:
// filterContext:
// 操作筛选器上下文。
//
// 异常:
// System.ArgumentNullException:
// filterContext 参数为 null。
public virtual void OnException(ExceptionContext filterContext);
}
}

ExceptionType:属性,相当于try catch(Exception)中的catch捕获的异常类型,默认所有异常类型。

View:异常展示视图,这个视图需要在目录Views/Shared/下。例如:

Order:该属性是父类FilterAttribute的一个属性,用来获取或者设置执行操作筛选器的顺序,默认-1,-1最先执行。

一个例子

在Index中直接抛出一个异常,我们现在需要做的就是通过HandlerError特性捕获到这个异常,并且在视图MyError上显示详细信息。

步骤1:添加特性

    public class UserController : Controller
{
// GET: User
[HandleError(ExceptionType = typeof(Exception), View = "MyError")]
public ActionResult Index()
{
throw new Exception("Sorry,threre is an error in your web server.");
} }

步骤2:定义错误视图,并通过@Model获取异常对象并显示错误信息。

@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
<div>
@Model.Exception.GetType().Name<br />
@Model.Exception.Message<br />
@Model.ControllerName<br />
@Model.ActionName<br />
@Model.Exception.StackTrace<br />
</div>
</body>
</html>

步骤3:注册过滤器。

在App_Start目录添加类FilterConfig

    public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}

在Global.asax中注册

    public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register); }
}

步骤4:开启自定义错误配置

  <system.web>
...
<customErrors mode="On"></customErrors>
</system.web>

测试

以上是采用ErrorHanlder的默认实现的方式,当然我们也可以自定义异常处理过滤器,方法很简单继承HandleErrorAttribute类,并且重写OnException方法即可。

    /// <summary>
/// 自定义异常过滤器
/// </summary>
public class CustomerErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
//如果没有处理该异常
if (!filterContext.ExceptionHandled)
{
if (filterContext.Exception.Message.Contains("Sorry,threre is an error in your web server."))
{
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Write("这是一个自定义异常处理过滤器");
}
}
}
}
    public class UserController : Controller
{
// GET: User
[CustomerError(ExceptionType = typeof(Exception), View = "MyError")]
public ActionResult Index()
{
throw new Exception("Sorry,threre is an error in your web server.");
} }
    public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new CustomerErrorAttribute());
}
}

测试

好了,自定义的异常处理过滤器已经起作用了。

需要注意在自定义处理异常过滤器的时候需要重写OnException方法,该方法有一个ExceptionContext类型的参数。

    // 摘要:
// 提供使用 System.Web.Mvc.HandleErrorAttribute 类的上下文。
public class ExceptionContext : ControllerContext
{
// 摘要:
// 初始化 System.Web.Mvc.ExceptionContext 类的新实例。
public ExceptionContext();
//
// 摘要:
// 使用指定的控制器上下文针对指定的异常初始化 System.Web.Mvc.ExceptionContext 类的新实例。
//
// 参数:
// controllerContext:
// 控制器上下文。
//
// exception:
// 异常。
//
// 异常:
// System.ArgumentNullException:
// exception 参数为 null。
public ExceptionContext(ControllerContext controllerContext, Exception exception); // 摘要:
// 获取或设置异常对象。
//
// 返回结果:
// 异常对象。
public virtual Exception Exception { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示是否已处理异常。
//
// 返回结果:
// 如果已处理异常,则为 true;否则为 false。
public bool ExceptionHandled { get; set; }
//
// 摘要:
// 获取或设置操作结果。
//
// 返回结果:
// 操作结果。
public ActionResult Result { get; set; }
}

需要注意的是,在自定义的异常过滤器中,如果对异常已经处理了,需要将ExceptionHandled设置为true,这样其它的过滤器可以根据该值判断当前异常是否已经处理过了。

通过异常处理过滤器的特性,你可以更方便的来处理action或者Controller中的异常,比try--catch用起来更方便,用这种方式,也可以简化异常处理的代码,少一些大块儿大块儿的异常处理代码。

[Asp.net MVC]HandleErrorAttribute异常过滤器的更多相关文章

  1. asp.net mvc HandleErrorAttribute 异常错误处理 无效!

    系统未知bug,代码没有深究. 现象:filters.Add(new HandleErrorAttribute()); 使用了全局的异常处理过滤. HandleErrorAttribute 核心代码: ...

  2. Asp.Net MVC<五>:过滤器

    ControllerActionInvoker在执行过程中除了利用ActionDescriptor完成对目标Action方法本身的执行外,还会执行相关过滤器(Filter).过滤器采用AOP的设计,它 ...

  3. ASP.NET MVC学习之过滤器篇(2)

    下面我们继续之前的ASP.NET MVC学习之过滤器篇(1)进行学习. 3.动作过滤器 顾名思义,这个过滤器就是在动作方法调用前与调用后响应的.我们可以在调用前更改实际调用的动作,也可以在动作调用完成 ...

  4. MVC 全局异常过滤器HandleErrorAttribute

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  5. 笨鸟先飞之ASP.NET MVC系列之过滤器(06异常过滤器)

    概念介绍 异常过滤器主要在我们方法中出现异常的时候触发,一般我们用 异常过滤器 记录日志,或者在产生异常时做友好的处理 如果我们需要创建异常过滤器需要实现IExceptionFilter接口. nam ...

  6. asp.net MVC之 自定义过滤器(Filter) - shuaixf

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration :缓存的时间, 以 ...

  7. ASP.NET MVC 4 (三) 过滤器

    先来看看一个例子演示过滤器有什么用: public class AdminController : Controller { // ... instance variables and constru ...

  8. asp.net MVC之 自定义过滤器(Filter)

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration:缓存的时间,以秒为 ...

  9. ASP.NET MVC学习之过滤器篇(1)

    一.前言 继前面四篇ASP.NET MVC的随笔,我们继续向下学习.上一节我们学习了关于控制器的使用,本节我们将要学习如何使用过滤器控制用户访问页面. 二.正文 以下的示例建立在ASP.NET MVC ...

随机推荐

  1. CF529B 【Group Photo 2 (online mirror version)】

    贪心枚举最后方案中最大的h,设为maxh若某个人i的wi与hi均大于maxh,则此方案不可行若某个人恰有一个属性大于maxh,则可确定他是否换属性剩下的人按wi-hi从大到小排序后贪心选择O(nlog ...

  2. VS Code折腾记 - (1)扯淡

    题外话 距离上篇介绍VSCode的文章已经过去四十多天,已经在正式项目作为主力开发工具了. 社区的发展非常快速,更新迭代够快,功能基本已经满足我所需了: 这个系列教程基于最新的vs code 1.8. ...

  3. Effective STL 学习笔记14: Use reserve to avoid unnecessary reallocations.

    vector 和 string 容器在动态插入一个新的对象时,如果容器内空间不够,该容器会: 重新分配空间 通常的做法是分配当前 Capacity 大小两倍的空间. 将旧空间中的所有元素拷贝进新的空间 ...

  4. java通过POI和easypoi实现Excel的导出

    前言 在工作经常会遇到excel导出报表的功能,自己也做过一些,然后在项目里看到同事封装的一个excel导出工具类,着实不错,拿来分享一下.然后,又在网上看到一个使用easypoi实现cxcel导出的 ...

  5. CCF CSP 201604-2 俄罗斯方块

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201604-2 俄罗斯方块 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游 ...

  6. input文本框 输入限制三则

    其一,只允许输入数字和小数点. <input onKeypress="return (/[\d.]/.test(String.fromCharCode(event.keyCode))) ...

  7. linux 101 hacks 3null 改文件大小写 xargs

    禁止标准输出和错误信息的输出 当我们调试 shell 脚本的时候,我们往往不希望看到标准输出和标准错误的信息.我们可以使用/dev/nulll 来禁止标准错误的信息. 将标准输出重定向到/dev/nu ...

  8. 将C++ IplImage 图像用C#读取

    如何将C++ IplImage 图像用C#读取  ? 将opencv 的C++程序做成 dll 动态链接库 用C#调用 当然这里需要安装emgucv  ,也可以自己实现这个类. 下面我把实现贴出来给大 ...

  9. Python之路【第十一篇】: 进程与线程

    阅读目录 一. cpython并发编程之多进程1.1 multiprocessing模块介绍1.2 Process类的介绍1.3 Process类的使用1.4 进程间通信(IPC)方式一:队列1.5 ...

  10. Intellij IDEA Cannot resolve symbol XXX 问题解决办法汇总

    maven项目遇到这类问题基本上是两方面的原因,类对应的依赖没有加载进来.编译器自身的设置和缓存问题. 解决第一类:1.检查项目的pom文件,是否必要的依赖都写清楚了: 2.是否使用自己的私有库,&l ...