□ 接口

public interface IExceptionFilter
{
    void OnException(ExceptionContext filterContext);
}

ExceptionContext继承于ControllerContext,从中可以获得路由数据route data、HttpContext。

□ 的HandleErrorAttribute是对IExceptionFilter的实现,默认是启用的

public static void RegisterGlobalFilters(GlobalFiltersCollection filters)
{
    filters.Add(new HandleErrorAttribute());
}

使用默认的HandleErrorAttribute

□ 让Shared/Error.cshtml的出错页报错

前提是,在Web.config中配置:

<customErrors mode="On"></customErrors>

□ 根据不同错误类型显示不同的错误页

[HandleError(ExceptionType = typeof(DbException),View = "")]
        [HandleError(ExceptionType = typeof(ApplicationException), View = "")]
        public ActionResult SomeAction()

□ HandleErrorAttribute的不足之处

1、只是显示错误页,无法记录错误日志
2、只能捕获500错误
3、不能捕获Controller以外的错误

继承HandleErrorAttribute自定义异常处理

使用log4net记录错误日志,并能记录AJAX错误,返回状态码为500的服务端错误。

需要一个显示错误信息的类:

namespace MvcApplication1.Models
{
    public class HandleErrorInfo
    {
        public HandleErrorInfo(Exception exception, string actionName, string controllerName)
        {
            this.Exception = exception;
            this.ControllerName = controllerName;
            this.ActionName = actionName;
        }
        public string ActionName { get; set; }
        public string ControllerName { get; set; }
        public Exception Exception { get; set; }
    }
}

引用log4net组件,继承HandleErrorAttribute自定义异常,使之能记录状态码为500的服务端错误,并能以json形式返回ajax相关异常。

using System.Web;
using System.Web.Mvc;
using log4net;
 
namespace MvcApplication1.Extension
{
    public class PowerfulHandleErrorAttribute : HandleErrorAttribute
    {
        private readonly ILog _logger;
 
        public PowerfulHandleErrorAttribute()
        {
            _logger = LogManager.GetLogger("MyLogger");
        }
 
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
            {
                return;
            }
 
            if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
            {
                return;
            }
 
            if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
            {
                return;
            }
 
            //如果是AJAX请求返回json
            if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
            {
                filterContext.Result = new JsonResult()
                {
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                    Data = new
                    {
                        error = true,
                        message = filterContext.Exception.Message
                    }
                };
            }
            else
            {
                var controllerName = (string)filterContext.RouteData.Values["controller"];
                var actionName = (string)filterContext.RouteData.Values["action"];
                var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
 
                filterContext.Result = new ViewResult()
                {
                    ViewName = View,
                    MasterName = Master,
                    ViewData = new ViewDataDictionary(model),
                    TempData = filterContext.Controller.TempData
                };
            }
 
            _logger.Error(filterContext.Exception.Message, filterContext.Exception);
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = 500;
 
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上PowerfulHandleErrorAttribute错误,只能处理服务端状态码500错误。还可以在全局中设置:当出现HttpException异常的时候,返回对应的错误提醒视图。

       //处理filter遗漏的错误
        protected void Application_Error(object sender, EventArgs e)
        {
            var httpContext = ((MvcApplication) sender).Context;
 
            var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
            var currentController = "";
            var currentAction = "";
            if (currentRouteData != null)
            {
                if (currentRouteData.Values["controller"] != null &&
                    !string.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
                {
                    currentController = currentRouteData.Values["controller"].ToString();
                }
 
                if (currentRouteData.Values["action"] != null &&
                    !string.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
                {
                    currentAction = currentRouteData.Values["action"].ToString();
                }
            }
 
            var ex = Server.GetLastError();
            var controller = new ErrorController();
            var routeData = new RouteData();
            var action = "Index";
            if (ex is HttpException)
            {
                var httpEx = ex as HttpException;
                switch (httpEx.GetHttpCode())
                {
                    case 404:
                        action = "NotFound";
                        break;
                    default:
                        action = "Index";
                        break;
                }
            }
 
            httpContext.ClearError();
            httpContext.Response.Clear();
            httpContext.Response.StatusCode = ex is HttpException ? ((HttpException) ex).GetHttpCode() : 500;
            httpContext.Response.TrySkipIisCustomErrors = true;
            routeData.Values["controller"] = "Error";
            routeData.Values["action"] = action;
 
            controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
            ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
        }
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

为此,还需要定义一个ErrorController,当然还有与之对应的错误提示视图:

using System.Web.Mvc;
 
namespace MvcApplication1.Controllers
{
    public class ErrorController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
 
        public ActionResult NotFound()
        {
            return View();
        }
 
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

使用ELMAH记录全局异常

using System.Web.Mvc;
using Elmah;
 
namespace MvcApplication1.Extension
{
    public class ElmahHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            base.OnException(filterContext);
 
            if (filterContext.ExceptionHandled)
            {
                ErrorSignal.FromCurrentContext().Raise(filterContext.Exception);
            }
        }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

参考资料:
Exception Handling in ASP.NET MVC

MVC扩展Filter,通过继承HandleErrorAttribute,使用log4net或ELMAH组件记录服务端500错误、HttpException、Ajax异常等的更多相关文章

  1. MVC扩展Filter, 通过继承AuthorizationAttribute限制IP

    为什么需要AuthorizationAttribute 在没有Authorization系统属性之前,我们可能这样判断:Request.IsAuthenticated && User. ...

  2. MVC扩展Filter,通过继承ActionFilterAttribute为登录密码加密

    与ActionFilter相关的接口有2个: □ IActionFilter 对action执行前后处理 void OnActionExecuting(ActionExecutingContext f ...

  3. MVC扩展ModelBinder,通过继承DefaultModelBinder把表单数据封装成类作为action参数

    把视图省.市.街道表单数据,封装成一个类,作为action参数.如下: action方法参数类型: namespace MvcApplication1.Models{    public class ...

  4. MVC文件上传04-使用客户端jQuery-File-Upload插件和服务端Backload组件实现多文件异步上传

    本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小  ...

  5. 17+个ASP.NET MVC扩展点【附源码】

    1.自定义一个HttpModule,并将其中的方法添加到HttpApplication相应的事件中!即:创建一个实现了IHttpmodule接口的类,并将配置WebConfig.  在自定义的Http ...

  6. .net mvc Authorization Filter,Exception Filter与Action Filter

    一:知识点部分 权限是做网页经常要涉及到的一个知识点,在使用MVC做权限设计时需要先了解以下知识: MVC中Url的执行是按照Controller->Action->View页面,但是我们 ...

  7. 16个ASP.NET MVC扩展点【附源码】

    转载于:http://www.cnblogs.com/wupeiqi/p/3570445.html 1.自定义一个HttpModule,并将其中的方法添加到HttpApplication相应的事件中! ...

  8. 基于log4net的日志组件扩展封装,实现自动记录交互日志 XYH.Log4Net.Extend(微服务监控)

    背景: 随着公司的项目不断的完善,功能越来越复杂,服务也越来越多(微服务),公司迫切需要对整个系统的每一个程序的运行情况进行监控,并且能够实现对自动记录不同服务间的程序调用的交互日志,以及通一个服务或 ...

  9. Asp.net 面向接口可扩展框架之“Mvc扩展框架及DI”

    标题“Mvc扩展框架及DI”有点绕口,我也想不出好的命名,因为这个内容很杂,涉及多个模块,但在日常开发又密不可分 首先说Mvc扩展框架,该Mvc扩展就是把以前的那个Mvc分区扩展框架迁移过来,并优化整 ...

随机推荐

  1. wordpress后台进去空白怎么办?

    最近博客换成了用wordpress程序搭建,内容和版面也重新设计.经常使用FTP工具,更改模板或者其他程序文件.由于对wordpress不太了解,竟然出现了wordpress后台进去空白的问题,而前台 ...

  2. AlexNet的参数优化

    优化算法的参数 论文中使用SGD算法,基本参数设置在前面优化算法的总结中已经提到了.这里要说几个个人体会. a. 原文中输入的batch数目是256,应该Alex经过调节后的结果,我实际用到的机器性能 ...

  3. Numpy的简单用法

    Numpy的简单用法 import numpy as np 一.创建ndarray对象 列表转换成ndarray: >>> a = [1,2,3,4,5] >>> ...

  4. php输出多余的空格或者空行

    1,文件是否有bom.可以通过脚步检测,或者利用notepa++打开,查看编码格式. 2.  <?php echo 'something'; ?>  或许是你的php标签外,有空格或者空行 ...

  5. 黑马程序员_java基础笔记(03)...面向对象

    ——————————  ASP.Net+Android+IOS开发..Net培训.期待与您交流!—————————— 1:面向对象的概念,2 : 类和对象的关系,3 : 封装,4 : 构造函数,5 : ...

  6. Springboot以war包方式运行

    一.  修改打包形式 在pom.xml里设置 <packaging>war</packaging>   二.添加以下依赖  提供标记嵌入式servlet容器 <depen ...

  7. 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]

    题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...

  8. JAVA语言中的运算符和表达式

    JAVA——运算符 按运算符要求的运算符个数可分为一元.二元.三元运算符: 一元运算符有一个操作数:如正数或者负数前面的“+”.“—”,和自增“++”.自减“- -”. 二元运算符有两个操作数:如除法 ...

  9. ZOJ2112 BZOJ1901 Dynamic Rankings 树套树 带修改的区间第k小

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 树套树,线段树套splay或者主席树套树状数组,我抄了一下hzwer ...

  10. wdcp(WDlinux Control Panel) 快速安装RPM包,lanmp一件安装

    lanmp一键安装包是wdlinux官网2010年开始推出的lamp,lnmp,lnamp(apache,nginx,php,mysql,zend,eAccelerator,pureftpd)应用环境 ...