【5min+】AspNet Core中的全域性異常處理
阿新 • • 發佈:2020-03-09
## **系列介紹**
【五分鐘的dotnet】是一個利用您的碎片化時間來學習和豐富.net知識的博文系列。它所包含了.net體系中可能會涉及到的方方面面,比如C#的小細節,AspnetCore,微服務中的.net知識等等。
5min+不是超過5分鐘的意思,"+"是知識的增加。so,它是讓您花費5分鐘以下的時間來提升您的知識儲備量。
## **正文**
其實一說到AspNet Core裡面的全域性異常,其實大家都不會陌生。因為這玩意兒用的非常頻繁,好的異常處理方案能夠幫助開發者更快速的定位問題,也能夠給使用者更好的使用者體驗。
比如,當您訪問到一個網頁,突然,它喵的報錯了!您沒有看錯,它報錯了!!!然後顯示了這樣的一個錯誤頁面:
![x](https://images.cnblogs.com/cnblogs_com/uoyo/1627547/o_200309082456QQ%E6%88%AA%E5%9B%BE20200309162017%E5%89%AF%E6%9C%AC.png)
請問,此刻電腦螢幕前的您會什麼感受。(*真想掏出那傳說中的95級史詩巨劍!*)
![x](https://images.cnblogs.com/cnblogs_com/uoyo/1627547/o_200309082951QQ%E6%88%AA%E5%9B%BE20200309163007.png)
但是,假若我們稍微處理一下這個異常,比如用咱們騰訊爸爸的手段,換個面板:
![x](https://images.cnblogs.com/cnblogs_com/uoyo/1627547/o_2003090827341.png)
使用者馬上就會想:“哎呀,錯誤就錯誤嘛,孰能無過,程式設計師鍋鍋也挺辛苦的。”
由此可見!!!全域性異常的捕獲和處理是有多麼的重要。
## **AspNet Core 中的全域性處理**
### **IAsyncExceptionFilter**
那麼在AspNet Core中我們該如何捕獲和處理異常呢? 可能很多同學都知道:`IExceptionFilter` 。 這個過濾器應該算是AspNet裡面的老牌過濾器了,從很早就延續至今,它允許咱們捕獲AspNet Core的控制器中的錯誤。不過,對於使用 `IExceptionFilter`,其實我更建議您考慮它的非同步版本: `IAsyncExceptionFilter`。(*別問為什麼,問就是愛的供養*)。
那麼我們來看看該過濾器是怎麼使用的呢? 下面以 `IAsyncExceptionFilter` 為例,對於同步版本其實也是一樣的:
```csharp
public class MyCustomerExceptionFilter : IAsyncExceptionFilter
{
public Task OnExceptionAsync(ExceptionContext context)
{
if (context.ExceptionHandled == false)
{
string msg = context.Exception.Message;
context.Result = new ContentResult
{
Content = msg,
StatusCode = StatusCodes.Status200OK,
ContentType = "text/html;charset=utf-8"
};
}
context.ExceptionHandled = true; //異常已處理了
return Task.CompletedTask;
}
}
```
上面咱們新建了一個自定義的異常過濾器,程式碼很簡單,就是報錯了之後依舊讓Http返回狀態碼為200的結果。並且將錯誤資訊返回到客戶端。
然後還需要在 `Startup.cs` 中,告訴 `MVC` 咱們新加的這個過濾器:
```csharp
services.AddControllers(options => options.Filters.Add(new MyCustomerExceptionFilter()));
```
然後就完了,是不是so easy? 來看看結果:
```csharp
[HttpGet]
public IEnumerable Get()
{
throw new Exception("has error!");
}
```
![x](https://images.cnblogs.com/cnblogs_com/uoyo/1627547/o_200309084727QQ%E6%88%AA%E5%9B%BE20200309164736.png)
如果不增加該過濾器,我們將得到Http狀態碼為500的響應。這對於某些不致命的意外操作來說,有點殺雞用牛刀的感覺,對於前端使用者來說也不是很友好(明明輸錯了一個字元,就直接被告知網站崩潰,並且出現喬殿下)。
而咱們捕獲了異常,進行特殊處理之後就顯得很友好了。(返回200,並且告訴使用者輸錯了某字元等)。
在上面的程式碼中,您會看到有一行 `context.ExceptionHandled = true;`。**注意!!!** 這很關鍵,當您處理完異常之後,請記得將此屬性更改為true,表明異常已經處理過了。如果不更改的話,嘿嘿