zoukankan      html  css  js  c++  java
  • MVC教程九:异常过滤器

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

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

    注意:

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

    演示示例:

    1、Error控制器代码如下:

     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         /// 测试数据库异常
    24         /// </summary>
    25         /// <returns></returns>
    26         [HandleError(ExceptionType = typeof(SqlException), View = "Error")]
    27         public ActionResult DbError()
    28         {
    29             // 错误的连接字符串
    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             // 访问一个不存在的文件
    44             System.IO.File.Open(@"D:error.txt",System.IO.FileMode.Open);
    45             // 返回Index视图
    46             return View("Index");
    47         }
    48     }
    49 }

     2、路由配置如下:

     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、配置文件如下:

    <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属性决定捕获的先后顺序,但最上面的异常必须是下面异常的同类级别或子类。如下图所示:

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

     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)] //不指定View,默认跳转到Share下面的Error视图
    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         /// 测试数据库异常
    25         /// </summary>
    26         /// <returns></returns>
    27         public ActionResult DbError()
    28         {
    29             // 错误的连接字符串
    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         public ActionResult IOError()
    41         {
    42             // 访问一个不存在的文件
    43             System.IO.File.Open(@"D:error.txt",System.IO.FileMode.Open);
    44             // 返回Index视图
    45             return View("Index");
    46         }
    47     }
    48 }

     在上面的示例中,捕获异常的时候只是跳转到了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>
    

    结果:

  • 相关阅读:
    node
    github
    [模块] pdf转图片-pdf2image
    python 15 自定义模块 随机数 时间模块
    python 14 装饰器
    python 13 内置函数II 匿名函数 闭包
    python 12 生成器 列表推导式 内置函数I
    python 11 函数名 迭代器
    python 10 形参角度 名称空间 加载顺序
    python 09 函数参数初识
  • 原文地址:https://www.cnblogs.com/dotnet261010/p/9005952.html
Copyright © 2011-2022 走看看