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抛出的异常"报错了!"。

其他的需要做更细致的处理的,就自由发挥了。

猜你喜欢

转载自blog.csdn.net/u012835032/article/details/115071416