我们平常在程序里面为了捕获异常, 会加上 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 =1, ExceptionType = typeof(SqlException), View = "Error")]
- [HandleError(Order =2, ExceptionType = typeof(IOException), View = "Error")]
- [HandleError(Order =3)] // 不指定 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>
结果:
来源: http://www.bubuko.com/infodetail-2591657.html