在程式設計中,我們會遇到各種各樣的異常問題,一個例外處理不僅僅可以幫助開發者快速的定位問題,也可以給使用者更好的使用體驗,那麼我們在AspNetCore專案中如何捕獲以及處理異常呢?
而對應AspNetCore程式,我們有兩種例外處理方案,它們分別是:
Masa Franework
作為一個框架,它為開發者以及使用者提供更好的開發體驗和使用體驗的例外處理功能
Masa.Utils.Exceptions
中定義了兩種異常類
UserFriendlyException
(友好異常)MasaException
(框架異常)並提供了兩種例外處理方案,那接下來就讓我們看看它們是如何使用的
根據需要自行選擇一種方案使用即可
專案基於.NET 6.0建立,必須安裝所必須的環境
基於中介軟體實現的全域性例外處理,用於捕捉應用程式異常,並將異常資訊處理後返回
Assignment.GlobalExceptionDemo
,並安裝Masa.Utils.Exceptions
dotnet new web -o Assignment.GlobalExceptionDemo
cd Assignment.GlobalExceptionDemo
dotnet add package Masa.Utils.Exceptions --version 0.6.0-rc.3 //提供全域性異常過濾器
User
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
Program
//支援處理自定義異常
app.UseMasaExceptionHandler(options =>
{
//支援處理自定義異常
options.ExceptionHandler = context =>
{
if (context.Exception is ArgumentNullException ex)
{
context.ToResult($"{ex.ParamName}不能為空");
}
};
});
app.MapPost("/register", (User user) =>
{
if (string.IsNullOrEmpty(user.Name))
throw new ArgumentNullException(nameof(user.Name));
//todo: Impersonate a registered user
});
更多使用技巧可檢視
基於MVC的全域性異常過濾器,用於捕捉應用程式異常,並將異常資訊處理後返回
Assignment.GlobalFilterDemo
,並安裝Masa.Utils.Exceptions
dotnet new web -o Assignment.GlobalFilterDemo
cd Assignment.GlobalFilterDemo
dotnet add package Masa.Utils.Exceptions --version 0.6.0-rc.3 //提供全域性異常過濾器
User
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
Program
builder.Services
.AddMvc()
//使用MasaException
.AddMasaExceptionHandler(options =>
{
options.ExceptionHandler = context =>
{
if (context.Exception is ValidationException ex)
{
string message = ex.Errors.Select(error => error.ErrorMessage).FirstOrDefault()!;
context.ToResult(message);
}
};
});
[ApiController]
[Route("[Action]")]
public class UserController : ControllerBase
{
[HttpPost]
public void Register(User user)
{
if (string.IsNullOrEmpty(user.Name))
throw new ArgumentNullException(nameof(user.Name));
//todo: Impersonate a registered user
}
}
分別啟用使用異常中介軟體的專案以及異常過濾器的專案,用Postman或者通過Swagger分別請求兩個專案的註冊使用者介面,其中Name
為空,可得到以下提示,則代表全域性例外處理成功
不論是通過中介軟體還是過濾器來處理全域性異常,我們都支援自定義例外處理,我們首先來看一下異常的處理流程
根據流程圖可以直觀的瞭解到,只要使用了Masa
提供的例外處理,哪怕我們不自定義異常,框架也會幫助我們按照無自定義異常流程預設處理異常資訊,但如果我們希望對特定的異常做出特定的響應,那麼就需要我們自定義異常
自定義異常支援三種方式
以中介軟體為例:
方案一. 通過設定ExceptionHandler
(例外處理),修改Program.cs
app.UseMasaExceptionHandler(options =>
{
options.ExceptionHandler = context =>
{
// 根據context.Exception判斷異常型別,並通過context.ToResult()輸出響應內容
if (context.Exception is ArgumentNullException ex)
{
context.ToResult($"{ex.ParamName}不能為空");
}
};
});
方案二. 通過自定義ExceptionHandler,並註冊到服務集合
ExceptionHandler
,並繼承IMasaExceptionHandler
/// <summary>
/// 建構函式引數需支援從IOC獲取
/// </summary>
public class ExceptionHandler : IMasaExceptionHandler
{
public void OnException(MasaExceptionContext context)
{
if (context.Exception is ArgumentNullException ex)
{
context.ToResult($"{ex.ParamName}不能為空");
}
}
}
Program.cs
builder.Services.AddSingleton<IMasaExceptionHandler, ExceptionHandler>();//註冊自定義異常
var app = builder.Build();
app.UseMasaExceptionHandler();// 在Program中執行例外處理程式
方案三. 通過自定義ExceptionHandler並指定ExceptionHandler來實現
ExceptionHandler
,並繼承IMasaExceptionHandler
/// <summary>
/// 建構函式引數需支援從IOC獲取
/// </summary>
public class ExceptionHandler : IMasaExceptionHandler
{
public void OnException(MasaExceptionContext context)
{
if (context.Exception is ArgumentNullException ex)
{
context.ToResult($"{ex.ParamName}不能為空");
}
}
}
Program.cs
app.UseMasaExceptionHandler(options => options.UseExceptionHanlder<ExceptionHandler>());//指定使用特定的例外處理程式
上述三種方案任選其一即可,提供的功能時一樣的,僅僅是寫法不同
MasaExceptionContext
預設提供了ToResult
方法支援輸入響應內容,狀態碼(預設: 299),內容型別 (預設:text/plain; charset=utf-8),我們可以根據自己的實際情況呼叫傳參即可
異常型別為UserFriendlyException
的預設紀錄檔等級為Information
,其餘異常的紀錄檔等級為Error
,那麼如果我想修改對應異常的紀錄檔等級應該怎麼做?
設定異常紀錄檔關係:
builder.Services.Configure<MasaExceptionLogRelationOptions>(options =>
{
options.MapLogLevel<ArgumentNullException>(LogLevel.None);
});
按照此方式,可以將型別為ArgumentNullException異常的紀錄檔等級設定為None(不記錄紀錄檔)
A: 為什麼使用全域性異常後沒有記錄紀錄檔?
Q:
A: 實現IMasaExceptionHandler
後,為什麼發生異常後沒有進入OnException
Q: 未注入到服務集合且沒有指定使用指定的ExceptionHanlder
public class ExceptionHandler : IMasaExceptionHandler
{
public void OnException(MasaExceptionContext context)
{
throw new NotImplementedException();
}
}
可參考自定義異常中的方案二或者方案三修改即可
Masa提供的全域性異常中介軟體,對自定義異常的擴充套件支援較好,並且後續Masa Framework
支援I18n後,全域性異常也將增加I18n支援, 屆時全域性異常會更加方便
Assignment13
https://github.com/zhenlei520/MasaFramework.Practice
MASA.Framework:https://github.com/masastack/MASA.Framework
MASA.EShop:https://github.com/masalabs/MASA.EShop
MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor
如果你對我們的 MASA Framework 感興趣,無論是程式碼貢獻、使用、提 Issue,歡迎聯絡我們
本文來自部落格園,作者:磊_磊,轉載請註明原文連結:https://www.cnblogs.com/zhenlei520/p/16789321.html
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利