ASP.NET Core 中間件的使用之全局異常處理機(jī)制
前言:
我們經(jīng)常聽到“秒修復(fù)秒上線”,覺(jué)得很厲害的樣子。
其實(shí)不然,這只是一個(gè)調(diào)侃而已,出現(xiàn)問(wèn)題的方式很多(邏輯漏洞、代碼異常、操作方式不正確等)。
我們今天來(lái)說(shuō)代碼異常問(wèn)題怎么快速定位,減少不必要的時(shí)間浪費(fèi)。
這就是今天的主題“添加全局異常處理機(jī)制”捕捉異常存儲(chǔ)到數(shù)據(jù)庫(kù)(mongodb、SqlServer、MySQL等)。
PS:輸出txt的話不怎么友好,不是所有人都能登錄服務(wù)器的。
異常是一種運(yùn)行時(shí)錯(cuò)誤,當(dāng)異常沒(méi)有得到適當(dāng)?shù)奶幚恚芸赡軙?huì)導(dǎo)致你的程序意外終止。
1、創(chuàng)建項(xiàng)目
我們創(chuàng)建一個(gè)ASP.NET Core Web API項(xiàng)目,選擇.NET Core3.1。

2、創(chuàng)建全局異常過(guò)濾器
在控制器里面創(chuàng)建一個(gè)異常過(guò)濾器,命名為ExceptionFilter.cs,過(guò)濾器繼承IExceptionFilter接口。
注意,我這里入庫(kù)用的是efcore+sqlserver,大家可以根據(jù)自己實(shí)際情況使用ORM和數(shù)據(jù)庫(kù)方式。
異常過(guò)濾器,顧名思義,就是當(dāng)程序發(fā)生異常時(shí)所使用的過(guò)濾器。用于在系統(tǒng)出現(xiàn)未捕獲異常時(shí)的處理。
實(shí)現(xiàn)一個(gè)自定義異常過(guò)濾器,自定義一個(gè)全局異常過(guò)濾器需要實(shí)現(xiàn)IExceptionFilter接口。
IExceptionFilter接口會(huì)要求實(shí)現(xiàn)OnException方法,當(dāng)系統(tǒng)發(fā)生未捕獲異常時(shí)就會(huì)觸發(fā)這個(gè)方法。
OnException方法有一個(gè)ExceptionContext異常上下文,其中包含了具體的異常信息,HttpContext及mvc路由信息。
系統(tǒng)一旦出現(xiàn)未捕獲異常后,比較常見的做法就是使用日志工具,將異常的詳細(xì)信息記錄下來(lái),方便修正調(diào)試。
下面是日志記錄的實(shí)現(xiàn):
using Microsoft.AspNetCore.Mvc.Filters;
using System;
namespace Log4NetWebAPI.Controllers
{
public class ExceptionFilter: IExceptionFilter
{
//全局異常處理機(jī)制
public void OnException(ExceptionContext context)
{
Exception ex = context.Exception;
//錯(cuò)誤所在的控制器方法名稱
var DisplayName = context.ActionDescriptor.DisplayName;
#region 錯(cuò)誤所在的行號(hào)行號(hào)
////行號(hào)前的名稱有的是中文,有的是英文,注意甄別
//var aaa = ex.StackTrace.Substring(ex.StackTrace.IndexOf("行號(hào)"), ex.StackTrace.Length - ex.StackTrace.IndexOf("行號(hào)"));
//var ccc = ex.StackTrace.Substring(ex.StackTrace.IndexOf("line"), ex.StackTrace.Length - ex.StackTrace.IndexOf("line"));
var lineNumber = 0;
const string lineSearch = ":line ";
var index = ex.StackTrace.LastIndexOf(lineSearch);
if (index != -1)
{
var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
var lineNumberStr = lineNumberText.Substring(0, lineNumberText.IndexOf("\r\n"));
if (int.TryParse(lineNumberStr, out lineNumber))
{
}
}
#endregion
#region 寫入信息到【數(shù)據(jù)庫(kù)】,這里自行入庫(kù)即可(mongodb、SqlServer、MySQL等),我以SqlServer為例
errorLog md = new errorLog();
md.logTime = DateTime.Now;
md.logType = "error";
md.displayName = DisplayName; //錯(cuò)誤位置
md.lineNumber = lineNumber; //錯(cuò)誤行號(hào)
md.message = ex.Message; //錯(cuò)誤信息
md.messagedetails = ex.ToString(); //錯(cuò)誤詳情
md.createTime= DateTime.Now;
using (var ctx = new dbContext())
{
ctx.Add(md);
ctx.SaveChanges();
}
#endregion
//下面是你的返回頁(yè)面顯示的內(nèi)容提示,以下省略
}
}
}
3、依賴注入全局異常處理機(jī)制
在Startup.cs里面把我們剛剛創(chuàng)建的全局異常處理機(jī)制注入到中間件來(lái),放到ConfigureServices方法里面。
//添加全局異常處理機(jī)制
services.AddMvc(option => {
option.Filters.Add<ExceptionFilter>();
});
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//添加全局異常處理機(jī)制
services.AddMvc(option => {
option.Filters.Add<ExceptionFilter>();
});
}
4、測(cè)試全局異常處理機(jī)制
“將string字符串轉(zhuǎn)換為int類型”,如下代碼,肯定是報(bào)錯(cuò)的,我們來(lái)捕捉一下錯(cuò)誤信息入庫(kù)。
var numberNo = "我是序列號(hào)";
//這里是轉(zhuǎn)換為int類型,然后數(shù)據(jù)源是string,肯定報(bào)錯(cuò),然后我們?nèi)植蹲?br /> //注意,我們這里沒(méi)有寫try catch
var number = Convert.ToInt32(numberNo);
運(yùn)行項(xiàng)目后我們查詢一下數(shù)據(jù)庫(kù),發(fā)現(xiàn)捕捉到錯(cuò)誤信息了,包括
錯(cuò)誤時(shí)間:2021-09-28 15:12:58.307
日志類型:error
錯(cuò)誤的方法位置:Log4NetWebAPI.Controllers.WeatherForecastController.Get (Log4NetWebAPI),
錯(cuò)誤的行號(hào):36行,
錯(cuò)誤的信息:Input string was not in a correct format.(輸入字符串的格式不正確。)

下面是控制器方法截圖


到此這篇關(guān)于ASP.NET Core 中間件的使用之全局異常處理機(jī)制的文章就介紹到這了,更多相關(guān)ASP.NET Core 全局異常處理機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET?Core使用Middleware設(shè)置有條件允許訪問(wèn)路由
這篇文章主要介紹了ASP.NET?Core使用Middleware設(shè)置有條件允許訪問(wèn)路由,文章圍繞主題相關(guān)資料展開學(xué)習(xí)內(nèi)容,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助2022-02-02
簡(jiǎn)單實(shí)現(xiàn).NET?Hook與事件模擬實(shí)例
這篇文章主要為大家介紹了簡(jiǎn)單實(shí)現(xiàn).NET?Hook與事件模擬實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
.NET 6新特性試用Timer類之PeriodicTimer?
這篇文章主要介紹了.NET 6新特性試用Timer類之PeriodicTimer,PeriodicTimer與其他Timer需要?jiǎng)?chuàng)建事件回調(diào)不同,下,下面文章詳細(xì)介紹PeriodicTimer的使用方式,需要的朋友可以參考一下2022-02-02
.NET?Core?中對(duì)象池?Object?Pool的使用
這篇文章主要介紹了?.NET?Core?中對(duì)象池?Object?Pool的使用,對(duì)象池簡(jiǎn)單來(lái)說(shuō)就是一種為對(duì)象提供可復(fù)用能力的軟件設(shè)計(jì)思路,對(duì)象池最常用的場(chǎng)景是游戲設(shè)計(jì),因?yàn)樵谟螒蛑写罅看嬖谥蓮?fù)用的對(duì)象,源源不斷的子彈出現(xiàn)并不是循環(huán)再生的,下面一起進(jìn)入文章了解具體內(nèi)容吧2021-11-11
.Net Core HttpClient處理響應(yīng)壓縮詳細(xì)
.Net Core作為后起之秀直接將HttpClient扶正,并且在此基礎(chǔ)上改良了HttpClientFactory,接下來(lái)我們就來(lái)探究一下在.Net Core中使用HttpClient處理響應(yīng)壓縮的機(jī)制。,需要的朋友可以參考下面文章的具體內(nèi)容2021-09-09
使用Asp.net Mvc3 Razor視圖方式擴(kuò)展JQuery UI Widgets方法介紹
jquery easyui grid或者extjs grid,jtable的代碼非常簡(jiǎn)潔、對(duì)于grid功能要求不是很復(fù)雜的情況下,強(qiáng)烈推薦大家使用2012-11-11
.net中線程同步的典型場(chǎng)景和問(wèn)題剖析
在使用多線程進(jìn)行編程時(shí),有一些經(jīng)典的線程同步問(wèn)題,對(duì)于這些問(wèn)題,.net提供了多種不同的類來(lái)解決2012-11-11
ASP.NET熱點(diǎn)問(wèn)題解答14個(gè)
ASP.NET熱點(diǎn)問(wèn)題解答14個(gè)...2006-07-07
深入分析XmlSerializer對(duì)象的Xml序列化與反序列化的示例詳解
本篇文章是對(duì)XmlSerializer 對(duì)象的Xml序列化與反序列化的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05

