We usually add try-catch-finally code in order to catch exceptions in the program, but this will make the program code look huge. In MVC, we can use exception filters to catch exceptions in the program, as shown in the following figure :
After using the exception filter, we don't need to write the exception handling code such as Try-Catch-Finally in the Action method, but leave this work to HandleError. This feature can also be applied to the Controller, or Applied to the Action aspect.
Notice:
When using an exception filter, the value of the attribute mode of the customErrors configuration section must be On.
Demonstration example:
1. The Error controller code is as follows:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.Data.SqlClient; 7 using System.IO; 8 9 namespace _3_异常过滤器.Controllers 10 { 11 public class ErrorController : Controller 12 { 13 // GET: Error 14 [HandleError(ExceptionType =typeof(ArithmeticException),View ="Error")] 15 public ActionResult Index(int a,int b) 16 { 17 int c = a / b; 18 ViewData["Result"] = c; 19 return View(); 20 } 21 22 /// < summary > 23 /// Test database exception 24 /// </ summary > 25 / // < returns ></ returns > 26 [HandleError(ExceptionType = typeof(SqlException), View = "Error")] 27 public ActionResult DbError() 28 { 29 // Bad connection string 30 SqlConnection conn = new SqlConnection(@"Initial Catalog=StudentSystem; Integrated Security=False;User Id=sa;Password=******;Data Source=127.0.0.1"); 31 conn.Open(); 32 // 返回Index视图 33 return View("Index"); 34 } 35 36 /// <summary> 37 /// IO异常 38 /// </summary> 39 /// <returns></returns> 40 [HandleError(ExceptionType = typeof(IOException), View = "Error")] 41 public ActionResult IOError() 42 { 43 // Access a non-existing file 44 System.IO.File.Open(@"D:\error.txt",System.IO.FileMode.Open); 45 // Return Index View 46 return View("Index"); 47 } 48 } 49 }
2. The routing configuration is as follows:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.Web.Routing; 7 8 namespace _3_异常过滤器 9 { 10 public class RouteConfig 11 { 12 public static void RegisterRoutes(RouteCollection routes) 13 { 14 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 16 routes.MapRoute( 17 name: "Default", 18 url: "{controller}/{action}/{id}", 19 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 ); 21 22 // 新增路由配置 23 routes.MapRoute( 24 name: "Default2", 25 url: "{controller}/{action}/{a}/{b}", 26 defaults: new { controller = "Home", action = "Index", a=0,b=0 } 27 ); 28 } 29 } 30 }
3. The configuration file is as follows:
<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 configuration section mode attribute value must be On--> <customErrors mode="On"> </customErrors> </system.web>
4. Running results
URL:http://localhost:21868/error/index/8/4
result:
URL:http://localhost:21868/error/index/8/0
result:
URL:http://localhost:21868/error/DbError
result:
URL:http://localhost:21868/error/IOError
result:
Multiple exceptions can be handled through HandleError on the same controller or Action method, and the order of capture is determined through the Order property, but the top exception must be the same level or subclass of the following exception. As shown below:
The above program can be modified into the following code:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.Data.SqlClient; 7 using System.IO; 8 9 namespace _3_异常过滤器.Controllers 10 { 11 [HandleError(Order =1, ExceptionType = typeof(SqlException), View = "Error")] 12 [HandleError(Order =2, ExceptionType = typeof (IOException), View = " Error " )] 13 [HandleError(Order = 3 )] // If View is not specified, it will jump to the Error view under Share by default 14 public class ErrorController : Controller 15 { 16 public ActionResult Index( int a, int b) 17 { 18 int c = a / b; 19 ViewData[ " Result " ] = c; 20 return View(); 21 } 22 23 /// <summary> 24 /// Test database exception 25 /// </summary> 26 /// <returns></returns> 27 public ActionResult DbError() 28 { 29 // Bad connection character String 30 SqlConnection conn = new SqlConnection( @" Initial Catalog=StudentSystem; Integrated Security=False;User Id=sa;Password=******;Data Source=127.0.0.1 " ); 31 conn.Open(); 32 // Return to Index view 33 return View(" Index " ); 34 } 35 36 /// <summary> 37 /// IO exception 38 /// </summary> 39 /// <returns></returns> 40 public ActionResult IOError() 41 { 42 / / Access a file that does not exist 43 System.IO.File.Open( @" D:\error.txt " ,System.IO.FileMode.Open); 44 // Return to the Index view 45 return View( " Index " ); 46 } 47 } 48 }