在 ASP.NET Core 中使用 Middleware 全域處理例外

栏目: ASP.NET · 发布时间: 4年前

内容简介:之前寫過一篇這裡會使用和這篇我們知道 ASP.NET Core 架構中,每個 Controller 是在處理每次 HTTP Context 的對應邏輯動作,當然我們可以在每個 Controller 中使用

之前寫過一篇 在 .NET Core 主控台應用程式中全域捕捉未處理的例外 ,主要是透過 .NET 應用程式的 AppDomain 類別下的 UnhandledException 來添加客製的例外處理,然而在 ASP.NET Core 專案中,內部會是個小型 Kestrel 網頁伺服器 在運作,因此大多數的 Exception 是不會往上傳遞並被 AppDomain.UnhandledException 接收到,所以這個方式是行不通的。但我們可以透過 ASP.NET Core 專案架構中的中介程序,捕捉發生在 HTTP Context 下的例外錯誤,這篇來做看看如何在中介程序(Middleware)中全域處理例外。

這裡會使用和這篇 收集 ASP.NET Core 網站所有的 HTTP Request 資訊 一樣的手法,都是透過 ASP.NET Core 中介程序來處理。

目標

我們知道 ASP.NET Core 架構中,每個 Controller 是在處理每次 HTTP Context 的對應邏輯動作,當然我們可以在每個 Controller 中使用 try...catch 語法來捕捉 Exception 例外,不過這樣會讓我們寫很多重複的程式碼。

如果系統中有個地方是 HTTP Context 一定都會經過的地方,且可以在那裏統一處理捕捉到的 Exception 例外,ASP.NET Core 的 Middleware 中介程序就是符合這樣的前提。

實作概念

從下圖我們可以看到,整個 HTTP Context 會經過一個個中介程序,像是 Pipeline 的處理流程,在最後一層 HTTP Context 會交由 MVC 來處理網站的邏輯動作,處理完後,會再一個個逆向回傳回去,這時有個 ExceptionHandle 中介程序,在這裡捕捉應用程式的例外狀況,就可以達到全域處理例外的效果。

在 ASP.NET Core 中使用 Middleware 全域處理例外

實作 ExceptionHandleMiddleware 中介程序

關於 ASP.NET Core 中介程序的用途說明及基本寫法,請參考 這篇官方文件

我們建立一個 ExceptionHandleMiddleware.cs 中介程序,這裡面將會是實作 HTTP Context 在 MVC 處理過程中發生例外時,要處理的對應動作。

public async Task Invoke(HttpContext context)
{
    try
    {
        await _next(context);
    }
    catch (Exception exception)
    {
        await HandleExceptionAsync(context, exception);
    }
}

這段程式碼很簡單,就只是用 try...catch 語法將串聯中介程序的 _next(context) 包起來,並且在發生例外時,執行 HandleExceptionAsync() 方法。

HandleExceptionAsync() 方法的時做,你可以參考下面的程式碼,會根據你的需求做調整:

private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
    context.Response.ContentType = "application/json";
    context.Response.StatusCode = StatusCodes.Status500InternalServerError;

    return context.Response.WriteAsync(
        $"{context.Response.StatusCode} Internal Server Error from the ExceptionHandle middleware."
    );
}

處理完中介程序的核心動作後,可以在 Startup.cs 檔案的 Configure() 要啟用 ExceptionHandleMiddleware 中介程序,你可以簡單用 app.UseMiddleware<ExceptionHandleMiddleware>(); 這樣的寫法來調用,但我個人比較喜歡再包一層 IApplicationBuilder 的擴充方法,一來我可以再調用前多做一些處理,二來是可以更優雅且有語意的啟用我們客製的中介程序,請參考下面 UseExceptionHandleMiddleware 擴充方法程式碼:

public static class ExceptionHandleMiddlewareExtensions
{
    public static IApplicationBuilder UseExceptionHandleMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<ExceptionHandleMiddleware>();
    }
}

如此一來,在 Startup.cs 檔案的 Configure() 中,使用 app.UseExceptionHandleMiddleware(); 這樣具有語意的寫法,可以讓程式碼讀起來更順暢。

在底下提供的範例專案中,如果開啟 https://localhost:44381/api/values 這個網址,則會丟出例外,並被中介程序捕捉到,畫面如下:

在 ASP.NET Core 中使用 Middleware 全域處理例外

本篇完整範例程式碼請參考 poychang/Demo-Global-Exception-Handle-WebApp

參考資料:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

生物信息学算法导论

生物信息学算法导论

N.C.琼斯 / 第1版 (2007年7月1日) / 2007-7 / 45.0

这是一本关于生物信息学算法和计算思想的导论性教科书,原著由国际上的权威学者撰写,经国内知名专家精心翻译为中文,系统介绍推动生物信息学不断进步的算法原理。全书强调的是算法中思想的运用,而不是对表面上并不相关的各类问题进行简单的堆砌。 体现了以下特色: 阐述生物学中的相关问题,涉及对问题的模型化处理并提供一种或多种解决方案: 简要介绍生物信息学领域领军人物; 饶有趣味的小插图使得概念更加具体和形象,方......一起来看看 《生物信息学算法导论》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具