□ 接口

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. Extjs 代码拾穗

    1.tree grid 添加一行 var rootNode = store.getRootNode(); var newRecord = Ext.create('MatrixDlv',{"s ...

  2. 浅谈malloc/free和new/delete 的区别

    malloc和new的区别 malloc是库函数,需要包头文件才能成功运行编译:new是操作符(C++中的关键字),需要在C++的环境下使用. malloc既可以在C语言中使用也可以在C++中使用,n ...

  3. SourceTree 3.0.17如何跳过注册进行安装? — git图形化工具(一)

    SourceTree 3.0.17个人版本的尝试跳过注册方式好几次都没成功,于是下载了企业版本https://www.sourcetreeapp.com/enterprise. 安装过程: 1.首次点 ...

  4. 自动化CI构建工具

    hudson/maven jenkins,bamboo, hudson

  5. centos7+python3.6+nginx+uwsgi+django2的搭建笔记

    公司需上线一套python编写的代码,需要给搭建一套环境  ,本次采用centos7+python3.6+nginx+uwsgi2+django2+mysql5.7的方式来进行搭建 写在部署前 在线上 ...

  6. 手工释放linux内存------/proc/sys/vm/drop_cache

    当在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching.这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法.那么我来谈谈这个问题 ...

  7. 004 Hadoop2.x基础知识

    一:大数据应用 1.Cloudera cloudera公司是Hadoop三大发行商之一,其版本为CDH版本,现在最新的版本是CDH5. 网站:http://archive.cloudera.com/c ...

  8. 《Android源码设计模式》--模板方法模式

    No1: 模板方法模式包括:抽象类(其中定义了一系列顺序方法).具体实现类A.具体实现类B 如果子类有实现不一样的细节,重写父类的某个方法即可 No2: AsyncTask对象调用execute方法后 ...

  9. 深度学习基础系列(七)| Batch Normalization

    Batch Normalization(批量标准化,简称BN)是近些年来深度学习优化中一个重要的手段.BN能带来如下优点: 加速训练过程: 可以使用较大的学习率: 允许在深层网络中使用sigmoid这 ...

  10. sort change from to range

    SORT FIELDS=COPY OUTREC FINDREP=(IN=X'05',OUT=X'40', STARTPOS=107,ENDPOS=204)