︿
Top
顯示具有 ASP.NET Core 8 MVC 標籤的文章。 顯示所有文章
顯示具有 ASP.NET Core 8 MVC 標籤的文章。 顯示所有文章

2024年3月23日 星期六

如何在 ASP.NET Core 8 MVC 應用程式使用 Serilog

How to use Serilog in ASP.NET Core 8 MVC application

前言

筆者在前兩篇有針對 "ASP.NET MVC 及 ASP.NET Core MVC 的錯誤處理" 作了描述. 對於錯誤處理(Error Handling) 作了以下定義: 係指錯誤取得 (Catch), 訊息規格 (Specification), 呈現 (Presentation), 及記錄 (Logging).

前兩篇涵蓋了 "錯誤取得" 及 "訊息規格", 尚餘 "呈現" 及 "記錄".

呈現 (Presentation):

需視需求而定. 由於對前端不是很專長, 這裡就先藏拙不表.

記錄 (Logging):

本文主要著重於此. 由於很多人推薦 Serilog, 所以, 就以此作為演練的對象. 一般而言, 記錄會包含以下幾個面向:

  • 記錄的層級 (Log Level).
    各個 Log 套件都有其 Log Level 的定義, 但大同小異.
  • 記錄的目標或提供者 (Log Target / Log Provider / Log Sinks).
    例如: Console, File, MSSQL, Seq. 前3者很明確, 不作贅述. 至於 Seq 則是一個集中的 Logging 服務 , 它提供了 Web UI 介面, 可以讓開發人員系統管理人員操作, 進行記錄的查詢.
  • 記錄的內容 (Log Content): 需視需求而定.

本文將以前述 "ASP.NET Core MVC Error Handling 摘要版" 的程式為基底, 繼續往下增修內容.

章節內容如下:

一. 內建 Logger 的功能
二. 加入 Serilog 相關套件
三. 輸出至 Console 及 File 入門
四. 利用 UseSerilogRequestLogging middleware 記錄 Http Request 內容
五. 自訂輸出格式
六. 輸出至 Seq Logging 服務入門
七. 輸出至 MSSQL 資料庫入門
   (一) 套件安裝
   (二) 由 Serilog.Sinks.MSSqlServer 決定預設的欄位及資料型態 (by appsettings.json)
   (三) Serilog.Sinks.MSSqlServer 欄位種類概述
   (四) 自訂 Serilog.Sinks.MSSqlServer 的欄位及資料型態 (by Program.cs)
   (五) 自訂 Serilog.Sinks.MSSqlServer 的欄位及資料型態 (for ProblemDetails by Program.cs)
   (六) 改用自定義的統一輸出格式 (MyProblemDetails)
   (七) 建立一層 LoggingService 打包 ILogger, 以利寫入資料庫欄位
八. 關於 Serilog 的增強器 (Enrichers)

範例存放於 GitHub, 有興趣的朋友, 可自行下載參考.

2024年2月23日 星期五

ASP.NET MVC 及 ASP.NET Core MVC 的錯誤處理

Error Handling in ASP.NET MVC and ASP.NET Core MVC

前言

有效的錯誤處理, 對於確保應用程式的穩定性和用戶體驗, 是非常重要的; 若系統沒有作好錯誤處理, 而呈現程式錯誤細節給使用者, 代表系統不穩定, 且用戶體驗會非常糟糕.

若您覺得這篇文章對您有幫助, 請不吝於在筆者的 GitHub Repository (可在 Repository 下載範例程式) 上按星星, 謝謝.

如果只關心 ASP.NET Core MVC 的實作程序及程式碼, 可以直接看筆者的另一篇文章: ASP.NET Core MVC Error Handling 摘要版 .

(一) 名詞定義

1.. 錯誤(Error): 係指框架 (ASP.NET 或 ASP.NET Core), 或應用程式自定義的例外 (Exception). 本文會說明如何將未通過資料檢核的錯誤, 包裝為自定義用戶端例外拋出. 以提供一致性的錯誤訊息規格.

2.. 錯誤處理(Error Handling): 係指錯誤取得 (Catch), 訊息規格 (Specification), 呈現 (Presentation), 及記錄 (Logging). 本文主要著重在錯誤取得及一致性錯誤訊息規格制訂.

(二) 錯誤取得機制概要

ASP.NET Core 提供了中介軟體 (Middleware) 的機制, 讓開發人員可以在整個 HTTP Request / Response 的過程中, 進行例外的攔截.

MVC 框架本身 (含 ASP.NET MVC 及 ASP.NET Core MVC) 提供了例外過濾器 (Exception Filter) 的機制, 讓開發人員在 HTTP 訊息進入 MVC 的生命週後, 進行例外的攔截.

理解 (Microsoft Learn) Filters in ASP.NET Core 的 2 張圖, 對開發人員而言, 是非常重要的.

若要完全處理整個 Web 應用程式的例外, 實作方面的相關配套如下:

1.. ASP.NET MVC: 要搭配 Web.config 或 Global.asax + 自定義的 ErrorController.

2.. ASP.NET Core MVC: 可以自行撰寫 ASP.NET Core 的例外處理中介軟體 (Middleware).
說明: Middleware 是屬於 ASP.NET Core, 不是 ASP.NET Core MVC; ASP.NET Core MVC 是建置在 ASP.NET Core 上的一個框架.

3.. ASP.NET Core 8 以後提供了實作 IExceptionHandler 介面的方式, 簡化例外處理 Middleware 的撰寫, 內建的 app.UseExceptionHandler(), 其實也是一佪 Middleware, 會使用前述的類別, 攔截例外. 只是筆者能力有限, 目前遇到無法取得 routeData (ex: controller, action 名稱) 的問題, 雖然本文還是有提供範例, 但暫不推薦此方式.

(三) 一致性的錯誤訊息規格概要

回傳一致性的錯誤訊息, 對於系統的開發及對用戶體驗, 是非常有幫助的.

1.. ASP.NET MVC: 只能自定義錯誤訊息類別.

2.. ASP.NET Core MVC: 可採用自定義錯誤訊息類別, 或內建的 ProblemDetails 類別.
說明: ASP.NET Core 2.1 起, 有一個依 IETF >RFC7807 規範 設計的 ProblemDetails 類別, 用以統一回傳結果. 但也可視需求, 自行定義統一的回傳類別.
說明: 本文採自定義的 ErrorViewModel 類別作為回傳格式, 作為說明之用. 但最後仍補上採用 ProblemDetails 類別的範例.

伺服端程式必須進行資料檢核, 才能去存取資料庫. 若資料檢核發現有誤, 代表用戶端沒有作好資料檢核的工作, 或者被瀏覽器的 F12 破解, 因此屬於用戶端的問題 (HTTP 4XX).

這類的錯誤, 需設計繼承自 Exception 類別的自定義例外類別, 當發生未通過檢核時, 打包為自訂例外拋出, 由前述的 Middleware 或 Exception Filter 攔截及處理.

上述的文字內容的思路, 可參考結論的流程圖.

(四) 章節內容

本文將探討 ASP.NET MVC 及 ASP.NET Core MVC 中一些錯誤處理實作技巧.

一. 預設的錯誤處理方式
二. 自定義統一的回傳的錯誤訊息規格
三. 自定義 Middleware, 用以產生貫穿 Request 軌跡的 TraceId
四. 撰寫 自定義例外 (Custom Exception), 供後續 Middleware 或 Filter 使用
五. 自定義 Middleware 攔截例外 (ASP.NET Core)
六. 建立 Exception Filter (ASP.NET MVC or ASP.NET Core MVC)
七. 實作 IExceptionHandler (ASP.NET Core 8 and later)
八. 建立另一個 MVC 專案, 參考前述的例外處理專案

目前 GitHub 上的範例版本為最後一版, 請下載參考. 輸出結果, 若發現回傳值有 JSON 欄位名稱字首大小寫的差異 (例如: TraceId vs. traceId), 或者有增加欄位 (例如: ControllerName, ActionName), 請再自行參酌程式碼. 前者是因為在輸出 JSON 時, 有對 System.Text.Json 作了一些選項的設定; 後者是因為要寫 Log 時, 需要該欄位.