首頁 > 軟體

ASP.NET MVC異常過濾器用法

2022-03-08 16:00:48

我們平常在程式裡面為了捕獲異常,會加上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檢視頁面如下:

結果:

到此這篇關於ASP.NET MVC異常過濾器用法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com