时间:2022-10-11 12:11:43 | 栏目:.NET代码 | 点击:次
我们平常在程序里面为了捕获异常,会加上try-catch-finally代码,但是这样会使得程序代码看起来很庞大,在MVC中我们可以使用异常过滤器来捕获程序中的异常,如下图所示:
使用了异常过滤器以后,我们就不需要在Action方法里面写Try -Catch-Finally这样的异常处理代码了,而把这份工作交给HandleError去做,这个特性同样可以应用到Controller上面,也可以应用到Action方面上面。
注意:
使用异常过滤器的时候,customErrors配置节属性mode的值,必须为On。
演示示例:
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"); } } }
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 } ); } } }
<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>
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视图页面如下:
结果: