1. 程式人生 > >ASP.NET Core Kestrel 隨機404錯誤

ASP.NET Core Kestrel 隨機404錯誤

visual question catch 最重要的 ESS -i 源碼 git 參考

一、Bug 出現

最近遇到一個很詭異的bug,Visual Studio 2017調試ASP.NET Core 2.2 Web程序的時候,隨機性的出現404錯誤。如下圖

技術分享圖片

事實上這個css文件是存在的,你刷新一下,可能又變成其他的css或js文件404。因此就想到可能是ASP.Net Core框架問題,下一步就準備調試一下源代碼。

二、.Net Core 源代碼調試

一開始用PDB Symbol符號去調試,如果你不了解這種調試方法,這篇文章可以幫到你 https://www.cnblogs.com/tdfblog/p/debugging-asp-net-core-2-source.html。
這種方式也可以看到底層代碼,但是不能修改代碼,並且F12跳轉方式也不太方便,你如果想在並發很多請求的時候,定位到是哪個請求404了,是比較困難的。但如果你對底層代碼比較熟悉,用這種方式方便快捷。

為了能找到bug原因,也是拼了,去github上下載了2.2版本的代碼。

技術分享圖片

然後我把和Kestrel相關的幾個項目都打開了,找到關鍵代碼,寫上自己的代碼,這是一種比較慢但在我看來,有效果的一種調試方式,仁者見仁智者見智吧。

技術分享圖片
 1                 string str = Environment.NewLine;
 2                 foreach (System.Reflection.PropertyInfo p in _request.GetType().GetProperties())
 3                 {
 4
try 5 { 6 object value = p.GetValue(_request, null); 7 if (value != null) 8 { 9 str += p.Name + ":" + value + Environment.NewLine; 10 }
11 } 12 catch (Exception ex) 13 { 14 string message = ex.Message; 15 var exception = ex.InnerException; 16 while (exception != null) 17 { 18 message += Environment.NewLine + exception.Message; 19 exception = exception.InnerException; 20 } 21 System.Diagnostics.Debug.WriteLine("%%%%%%%%%%%%%%% " + message); 22 } 23 } 24 System.Diagnostics.Debug.WriteLine(str);
View Code

最重要的是項目生成之後,把生成的dll覆蓋到ASP.NET Core運行時目錄。查看運行時文件位置可以在代碼裏這樣。

string path = typeof(StaticFileMiddleware).Assembly.CodeBase;

我這邊的目錄是 C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\2.2.1,就把剛剛從ASP.NET Core源碼生成的dll覆蓋到這個目錄。
然後在Visual Studio的Windows->Output窗口就能看到輸出了。

技術分享圖片

三、問題解決

花了好幾天調試,沒有找到原因,最後到GitHub ASP.NET Core的Issues裏面找到了原因,就是HttpContext被銷毀後,就不能在異步任務裏面用IHttpContextAccessor獲取了,這個時候獲取不是null,獲取的是一個非空對象,會影響下一次請求。Anyway,在異步任務(非主線程)裏用HttpContext一定要小心。

重要參考:

https://github.com/aspnet/KestrelHttpServer/issues/2591

https://stackoverflow.com/questions/50661923/signalr-core-1-0-intermittently-changes-the-case-of-http-method-for-non-signalr

ASP.NET Core Kestrel 隨機404錯誤