我们平常在程序里面为了捕获异常,会加上try-catch-finally代码,但是这样会使得程序代码看起来很庞大,在MVC中我们可以使用异常过滤器来捕获程序中的异常,如下图所示:

使用了异常过滤器以后,我们就不需要在Action方法里面写Try -Catch-Finally这样的异常处理代码了,而把这份工作交给HandleError去做,这个特性同样可以应用到Controller上面,也可以应用到Action方面上面。

注意:

使用异常过滤器的时候,customErrors配置节属性mode的值,必须为On。

演示示例:

1、Error控制器代码如下:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
using System.IO; namespace _3_异常过滤器.Controllers
{
public class ErrorController : Controller
{
// GET: Error
[HandleError(ExceptionType =typeof(ArithmeticException),View ="Error")]
public ActionResult Index(int a,int b)
{
int c = a / b;
ViewData["Result"] = c;
return View();
} /// <summary>
/// 测试数据库异常
/// </summary>
/// <returns></returns>
[HandleError(ExceptionType = typeof(SqlException), View = "Error")]
public ActionResult DbError()
{
// 错误的连接字符串
SqlConnection conn = new SqlConnection(@"Initial Catalog=StudentSystem; Integrated Security=False;User Id=sa;Password=******;Data Source=127.0.0.1");
conn.Open();
// 返回Index视图
return View("Index");
} /// <summary>
/// IO异常
/// </summary>
/// <returns></returns>
[HandleError(ExceptionType = typeof(IOException), View = "Error")]
public ActionResult IOError()
{
// 访问一个不存在的文件
System.IO.File.Open(@"D:\error.txt",System.IO.FileMode.Open);
// 返回Index视图
return View("Index");
}
}
}

2、路由配置如下:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing; namespace _3_异常过滤器
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
); // 新增路由配置
routes.MapRoute(
name: "Default2",
url: "{controller}/{action}/{a}/{b}",
defaults: new { controller = "Home", action = "Index", a=0,b=0 }
);
}
}
}

3、配置文件如下:

<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>
<!--customErrors配置节mode的属性值必须为On-->
<customErrors mode="On">
</customErrors>
</system.web>

4、运行结果

URL:http://localhost:21868/error/index/8/4

结果:

URL:http://localhost:21868/error/index/8/0

结果:

URL:http://localhost:21868/error/DbError

结果:

URL:http://localhost:21868/error/IOError

结果:

在同一个控制器或Action方法上可以通过HandleError处理多个异常,通过Order属性决定捕获的先后顺序,但最上面的异常必须是下面异常的同类级别或子类。如下图所示:

上面的程序可以修改成如下的代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
using System.IO; namespace _3_异常过滤器.Controllers
{
[HandleError(Order =, ExceptionType = typeof(SqlException), View = "Error")]
[HandleError(Order =, ExceptionType = typeof(IOException), View = "Error")]
[HandleError(Order =)] //不指定View,默认跳转到Share下面的Error视图
public class ErrorController : Controller
{
public ActionResult Index(int a,int b)
{
int c = a / b;
ViewData["Result"] = c;
return View();
} /// <summary>
/// 测试数据库异常
/// </summary>
/// <returns></returns>
public ActionResult DbError()
{
// 错误的连接字符串
SqlConnection conn = new SqlConnection(@"Initial Catalog=StudentSystem; Integrated Security=False;User Id=sa;Password=******;Data Source=127.0.0.1");
conn.Open();
// 返回Index视图
return View("Index");
} /// <summary>
/// IO异常
/// </summary>
/// <returns></returns>
public ActionResult IOError()
{
// 访问一个不存在的文件
System.IO.File.Open(@"D:\error.txt",System.IO.FileMode.Open);
// 返回Index视图
return View("Index");
}
}
}

在上面的示例中,捕获异常的时候只是跳转到了Error视图,如果我们想获取异常的具体信息该怎么办呢?如下图所示:

查看MVC源码,可以发现HandleError返回的是HandleErrorInfo类型的model,利用该model可以获取异常的具体信息,修改Error视图页面如下:

@model HandleErrorInfo
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width" />
<title>错误</title>
<style type="text/css">
p{
color:red;
}
</style>
</head>
<body>
@*<hgroup>
<h1>错误。</h1>
<h2>处理你的请求时出错。</h2>
</hgroup>*@
<p>
抛错控制器:<b>@Model.ControllerName</b>  抛错方法:<b>@Model.ActionName</b>  抛错类型:<b>@Model.Exception.GetType()</b>
</p>
<p>
异常信息:@Model.Exception.Message
</p>
<p>
堆栈信息:@Model.Exception.StackTrace
</p>
</body>
</html>

结果:

最新文章

  1. Codevs2157 配对
  2. 蓝牙的L2CAP协议
  3. [CrunchBang]禁止“桌面上鼠标滚轮切换工作区桌面“
  4. 199bit总结的影响最大的十个算法
  5. js点击事件代理时切换图片如何防抖动
  6. leetcode 第41题 Trapping Rain Water
  7. Unity游戏程序员面试题及解答
  8. Java 中冷门的 synthetic 关键字原理解读
  9. 基于Flink秒级计算时CPU监控图表数据中断问题
  10. windows NLB实现MSSQL读写分离--从数据库集群读负载均衡
  11. java算法01 - 链表
  12. Velocity日期格式化
  13. BZOJ 2759 一个动态树好题(动态树)
  14. vuex学习及使用
  15. Ubuntu(16.04.2)学习笔记(一)如何解决dpkg: error processing install-info
  16. Adam算法
  17. Apache服务器笔记
  18. 用php实现交互式工具——How do I write a command-line interactive PHP script?
  19. Python练习题--持续更新
  20. python-面向过程编程

热门文章

  1. Google Mesa概览
  2. 如果使用EntityFramework6链接Mysql
  3. 菜鸟学数据库(五)——MySQL必备命令
  4. kernel dump Analysis
  5. [Windows Azure] Managing SQL Database using SQL Server Management Studio
  6. 【Redis】Redis的基本安装及使用、Jedis的基本使用、spring-data-redis的集成、主从模式、哨兵模式
  7. 【转】Mysql千万级数据表结构修改
  8. python解析XML笔记(etree)
  9. ubuntu下上传本地代码到github
  10. egret list不显示问题