天天看點

ASP.NET MVC 利用IExceptionFilter實作異常統一處理

環境:ASP.NET MVC

在開始前,需要了解下面兩個概念:

FilterAttribute:表示操作和結果篩選器特性的基類。

IExceptionFilter:定義異常篩選器所需的方法。

IExceptionFilter.OnException():在發生異常時調用。

namespace System.Web.Mvc
{
    //
    // 摘要:
    //     定義異常篩選器所需的方法。
    public interface IExceptionFilter
    {
        //
        // 摘要:
        //     在發生異常時調用。
        //
        // 參數:
        //   filterContext:
        //     篩選器上下文。
        void OnException(ExceptionContext filterContext);
    }
}
           

下面是具體操作: 

1、在Web項目下面建一個Filters檔案夾,添加一個類ExceptionFilter 。

2、繼承FilterAttribute, IExceptionFilter,重寫IExceptionFilter的OnException。

A、記錄日志;

B、Ajax和非Ajax分開處理

using System.Net;
using System.Web.Mvc;

namespace Test.Web.Filters
{
    public class ExceptionFilter : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            //記錄錯誤日志
            LogHelper.Error(filterContext.Exception.Message, filterContext.Exception);

            //判斷是否為ajax請求
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                //Ajax 輸出錯誤資訊給腳本
                filterContext.Result = AjaxError(filterContext);
            }
            else
            {
                //非ajax請求跳轉至統一錯誤頁面
                filterContext.Result = new RedirectResult(
                    string.Format("../error.html?Code={0}&Source={1}", 500, filterContext.RequestContext.HttpContext.Request.RawUrl));
            }

            //記錄異常日志(往發生異常的類)
            filterContext.ExceptionHandled = true;//聲明異常已處理
        }

        /// <summary>
        /// 處理Ajax的錯誤
        /// </summary>
        /// <param name="filterContext">過濾器上下文</param>
        /// <returns>json</returns>
        protected JsonResult AjaxError(ExceptionContext filterContext)
        {
            //将響應狀态代碼設定為500
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            //在派生類中重寫時,擷取或設定一個值,該值指定是否禁用 IIS 7.0 自定義錯誤。
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            return new JsonResult
            {
                Data = filterContext.Exception.Data,
                ContentEncoding = System.Text.Encoding.UTF8,
                JsonRequestBehavior = JsonRequestBehavior.DenyGet
            };
        }

    }
}
           

3、建立一個控制器基類BaseController,把上面的建好的過濾器加上去。

using System.Web.Mvc;
using Test.Web.Filters;

namespace Test.Web.Controllers
{
    [ExceptionFilter]
    public class BaseController : Controller
    {
    }
}
           

4、其他控制器繼承BaseController,就可以捕獲異常了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Test.Web.Controllers
{
    public class HomeController : BaseController
    {
        public ActionResult Index()
        {
            throw new Exception("報錯了!");

            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}
           

在ExceptionFilter的OnException斷點,可以看到在/Home/Index抛出的異常"報錯了!"。

ASP.NET MVC 利用IExceptionFilter實作異常統一處理

其他的需要做更細緻的處理的,就自由發揮了。