一、异常过滤器
异常筛选器用于实现IExceptionFilter接口,并在ASP.NET MVC管道执行期间引发了未处理的异常时执行。异常筛选器可用于执行诸如日志记录或显示错误页之类的任务。HandleErrorAttribute类是异常筛选器的一个示例。
先来看看HandleErrorAttribute类的定义:
#region 程序集 System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// D:\Practice\MVC\自定义异常过滤器\MVCCuetomerExcepFilter\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll
#endregion
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:
// 操作筛选器上下文。
//
// 异常:
// T:System.ArgumentNullException:
// filterContext 参数为 null。
public virtual void OnException(ExceptionContext filterContext);
}
}
从代码中可以看出HandleErrorAttribute继承了IExceptionFilter接口,并且有一个虚方法,如果要自定义异常过滤器,只需要继承HandleErrorAttribute类并重写HandleErrorAttribute类里面的虚方法即可。
二、示例
1、创建异常类
新建一个ExceptionFilters类继承自HandleErrorAttribute,并重写OnException方法,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCCuetomerExcepFilter.Extension
{
/// <summary>
/// 异常过滤器
/// </summary>
public class ExceptionFilters : HandleErrorAttribute
{
/// <summary>
/// 在异常发生时调用
/// </summary>
/// <param name="filterContext"></param>
public override void OnException(ExceptionContext filterContext)
{
// 判断是否已经处理过异常
if(!filterContext.ExceptionHandled)
{
// 获取出现异常的controller和action名称,用于记录
string strControllerName = filterContext.RouteData.Values["controller"].ToString();
string strActionName = filterContext.RouteData.Values["action"].ToString();
// 定义一个HandleErrorInfo,用于Error视图展示异常信息
HandleErrorInfo info = new HandleErrorInfo(filterContext.Exception, strControllerName, strActionName);
ViewResult result = new ViewResult
{
ViewName = this.View,
// 定义ViewData,泛型
ViewData = new ViewDataDictionary<HandleErrorInfo>(info)
};
// 设置操作结果
filterContext.Result = result;
// 设置已经处理过异常
filterContext.ExceptionHandled = true;
}
//base.OnException(filterContext);
}
}
}
2、创建控制器
新建一个控制器,代码如下:
using MVCCuetomerExcepFilter.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCCuetomerExcepFilter.Controllers
{
public class ExceptionController : Controller
{
// GET: Exception
/// <summary>
/// View表示发生异常时指定的视图
/// 这里表示发生异常时使用ExceptionDetails视图
/// </summary>
/// <returns></returns>
[ExceptionFilters(View =("ExceptionDetails"))]
public ActionResult Index()
{
// 测试抛出异常
throw new NullReferenceException("测试抛出的异常");
}
}
}
异常发生时使用ExceptionDetails视图,所以在Shared文件夹里面新建ExceptionDetails视图,代码如下:
<!--使用强类型视图-->
@model System.Web.Mvc.HandleErrorInfo
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>异常</title>
</head>
<body>
<p>
抛错控制器:<b>@Model.ControllerName</b> 抛错方法:<b>@Model.ActionName</b> 抛错类型:<b>
@Model.Exception.GetType().Name
</b>
</p>
<p>
异常信息:<b>@Model.Exception.Message</b>
</p>
<p>
堆栈信息:
</p>
<pre>@Model.Exception.StackTrace</pre>
</body>
</html>
三、测试
运行程序,访问Exception控制器的Index方法,效果如下:
四、总结
上面的案例演示了一个自定义异常类,很明显比HandleError要灵活,在自定义异常类里面可以写很多与业务相关的代码。
GitHub代码地址:https://github.com/jxl1024/CustomerHandleErrorFilter
到此这篇关于ASP.NET MVC自定义异常过滤器的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。