Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 718|回复: 0

.NET MVC全局异常处理(二)

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-21 23:46:06 | 显示全部楼层 |阅读模式

    .NET MVC全局异常处理(二)

    对上节的内容进行了补充

    MVC过滤器Filter

    MVC有四种过滤器:Authorization、Exception、Action、Result,我们要用的的就是Exception异常过滤器

    当我们新建一个MVC项目后,异常过滤器就已经自动在程序中注册了,先从上一节所说的全局配置文件开始,Global.asax这个文件中的Application_Start方法会在程序启动时运行,其中的即默认注册了全局过滤器,如图

    我们可以进入RegisterGlobalFilters方法查看,这个方法中默认注册了一个异常处理过滤器,也就是说默认状态的MVC程序发生异常时会被程序捕获处理,处理方式是跳转至错误页面,也就是上一篇文章说的Layout文件夹下面的Error页

    但使用异常过滤器有一个大前提是要在Web.config中打开自定义错误处理的设置,customErrors节点要设置为“On”,这一设置默认是关闭的,也就是说要手动加上才行

    <system.web>
      <compilation debug="true" targetFramework="4.6.1"/>
      <httpRuntime targetFramework="4.6.1"/>
      <customErrors mode="On">
      </customErrors>
    </system.web>
    

    需要注意的是 404 错误,这种类型的异常并不会被过滤器捕获

    但是可以在web.config中添加节点进行自定义配置,跳转到相应的页面

    <customErrors mode="On">
      <error redirect="~/Error/NotFound" statusCode="404" />
    </customErrors>
    
    public class ErrorController : Controller
    {
        // GET: Error
        public ActionResult Index()
        {
            return View();
        }
    
        public ActionResult CustomHttpError()
        {
            ViewBag.Message = "有错误";
            //HandleErrorInfo
            //ExceptionContext
    
            return View();
        }
        public ActionResult NotFound()
        {
            return View();
        }
    }
    

    自定义过滤器

    MVC默认的异常过滤器可以满足基本的需要,但是如果要对一些异常进行特殊处理就需要我们自定义过滤器的内容,可以通过重写OnException方法达到这个目的

    public class CustomHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            /* 调用基类的OnException方法,实现基础的功能。
             * 如果要完全的自定义,就不需要调用基类的方法
             */
            base.OnException(filterContext);
    
            /* 此处可进行记录错误日志,发送错误通知等操作
             * 通过Exception对象和HttpException对象可获取相关异常信息。
             * Exception exception = filterContext.Exception;
             * HttpException httpException = new HttpException(null, exception);
             */
        }
    }
    

    示例代码

    public class MyErrorHandler : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
                return;
    
            var statusCode = (int) HttpStatusCode.InternalServerError;
            if (filterContext.Exception is HttpException)
            {
                statusCode = filterContext.Exception.As<HttpException>().GetHttpCode();
            }
            else if (filterContext.Exception is UnauthorizedAccessException)
            {
                //to prevent login prompt in IIS
                // which will appear when returning 401.
                statusCode = (int)HttpStatusCode.Forbidden;
            }
            _logger.Error("Uncaught exception", filterContext.Exception);
    
            var result = CreateActionResult(filterContext, statusCode);
            filterContext.Result = result;
    
            // Prepare the response code.
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = statusCode;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    
        protected virtual ActionResult CreateActionResult(ExceptionContext filterContext, int statusCode)
        {
            var ctx = new ControllerContext(filterContext.RequestContext, filterContext.Controller);
            var statusCodeName = ((HttpStatusCode) statusCode).ToString();
    
            var viewName = SelectFirstView(ctx,
                                           "~/Views/Error/{0}.cshtml".FormatWith(statusCodeName),
                                           "~/Views/Error/General.cshtml",
                                           statusCodeName,
                                           "Error");
    
            var controllerName = (string) filterContext.RouteData.Values["controller"];
            var actionName = (string) filterContext.RouteData.Values["action"];
            var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
            var result = new ViewResult
                             {
                                 ViewName = viewName,
                                 ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
                             };
            result.ViewBag.StatusCode = statusCode;
            return result;
        }
    
        protected string SelectFirstView(ControllerContext ctx, params string[] viewNames)
        {
            return viewNames.First(view => ViewExists(ctx, view));
        }
    
        protected bool ViewExists(ControllerContext ctx, string name)
        {
            var result = ViewEngines.Engines.FindView(ctx, name, null);
            return result.View != null;
        }
    }
    
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 11:15 , Processed in 0.055090 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表