zoukankan      html  css  js  c++  java
  • ASP.NET Core中,UseDeveloperExceptionPage扩展方法会吃掉异常

    在ASP.NET Core中Startup类的Configure方法中,有一个扩展方法叫UseDeveloperExceptionPage,如下所示:

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
    
        app.UseStaticFiles();
        app.UseCookiePolicy();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

    UseDeveloperExceptionPage方法是所属DeveloperExceptionPageExtensions类的IApplicationBuilder扩展方法,这个方法是新建ASP.NET Core项目时默认加入Startup类中的,它的作用是ASP.NET Core在开发环境(Development环境)下用于展示异常信息页面,如下所示:

    但是UseDeveloperExceptionPage方法有一个很坑的特性,那就是它会吃掉ASP.NET Core中Middleware管道中的异常。

    我们来设想,假如我们定义了下面一个Middleware叫LoggerMiddleware,它使用try catch代码块,来记录所有发生在ASP.NET Core的Middleware管道中抛出的异常到日志:

    public class LoggerMiddleware
    {
        private readonly RequestDelegate next;
    
        public LoggerMiddleware(RequestDelegate next)
        {
            this.next = next;
        }
    
        public async Task Invoke(
            Microsoft.AspNetCore.Http.HttpContext context)
        {
            Logger logger = LogManager.GetCurrentClassLogger();
            //logger.Log(NLog.LogLevel.Info, "Log tracking start!");
    
            try
            {
                await next.Invoke(context);
            }
            catch (Exception ex)
            {
                LogMessageGenerator logMessageGenerator = new LogMessageGenerator(() =>
                {
                    return ex.GetType().FullName + "
    " + ex.StackTrace;
                });
    
                logger.Log(NLog.LogLevel.Error, ex, logMessageGenerator);
                throw;
            }
    
            //logger.Log(NLog.LogLevel.Info, "Log tracking end!");
        }
    }

    还有其扩展类LoggerMiddlewareExtension:

    public static class LoggerMiddlewareExtension
    {
        public static void UsePipelineLogger(this IApplicationBuilder app)
        {
            app.UseMiddleware<LoggerMiddleware>();
        }
    }

    然后我在ASP.NET Core中Startup类的Configure方法中,将其(app.UsePipelineLogger)放在app.UseDeveloperExceptionPage方法前面:

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UsePipelineLogger();
    
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
    
        app.UseStaticFiles();
        app.UseCookiePolicy();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

    然后你会发现当MVC Controller中抛出异常时,LoggerMiddleware中的try catch代码块捕获不到任何异常。最开始我相当纳闷,这异常怎么活生生地就被吃掉了呢?

    后来我在ASP.NET Core中Startup类的Configure方法中,将app.UsePipelineLogger放在了app.UseDeveloperExceptionPage后面:

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
    
        app.UsePipelineLogger();
    
        app.UseStaticFiles();
        app.UseCookiePolicy();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

    这下LoggerMiddleware中的try catch代码块就成功捕获到了MVC Controller中抛出的异常,这很明确地证明了是app.UseDeveloperExceptionPage方法的Middleware吃掉了ASP.NET Core管道中的异常。

    虽然不知道app.UseExceptionHandler方法是不是也会吃掉异常,但是建议大家把捕获异常的Middleware(本例的app.UsePipelineLogger)方法,都放在app.UseDeveloperExceptionPage和app.UseExceptionHandler的后面!

  • 相关阅读:
    微信小程序设置底部导航栏目方法
    微信小程序四(设置底部导航)
    微信小程序三(设置页面标题)
    error while loading shared libraries: libpcre.so.0的解决办法(转)
    mysql无法启动问题的解决方案:mysql.sock重启不自动生成,mysqld_safe启动报错
    使用snmp+mrtg监控CPU、流量、磁盘空间、内存
    lvs之dr技术的学习与实践
    lvs之nat技术的学习与实践
    lvs之ip-tun(ip隧道)技术的学习与实践
    CentOS 6.4下Squid代理服务器的安装与配置【转】
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/10175361.html
Copyright © 2011-2022 走看看