• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
PowerCoder
博客园    首页    新随笔    联系   管理    订阅  订阅

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 + "\r\n" + 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的后面!

 

posted @ 2018-12-25 17:32  PowerCoder  阅读(3229)  评论(1)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3