ASP.NET MVC 執行 Response.End() 不會中斷

依照之前的經驗,執行 Response.End() 後會立即中斷並跳離執行

但是在ASP.NET中,卻無法成功,導致我想用try catch不顯示Exception時有點困擾
(單純想用Message來進行溝通而不是進入MS的error頁面)

又或者是,明明在第二層副程式就因為讀取失敗而進入error,但是卻執行完之後回到第一層程式,再因為沒抓到資料而進入錯誤,但是副程式的錯誤可能是無法讀取資料庫,跟輸出的錯誤內容就不一致了
(從 SqlException 變成 NullException)

後來爬文之後發現問題在於 ASP.NET MVC的判斷方式 Response的判斷方式,是依靠ASP.NET傳送來的資料進行判斷,其中判斷中斷的是IsInCancellabelPeriod 而這個值又是依靠_TimeOutState來進行判斷。

/// <devdoc> /// <para>Sends all currently buffered output to the client then closes the /// socket connection.</para> /// </devdoc> public void End() { if (_context.IsInCancellablePeriod) { AbortCurrentThread(); } else { // when cannot abort execution, flush and supress further output _endRequiresObservation = true; if (!_flushing) { // ignore Reponse.End while flushing (in OnPreSendHeaders) Flush(); _ended = true; if (_context.ApplicationInstance != null) { _context.ApplicationInstance.CompleteRequest(); } } } }

而這個值在WebForm和MVC裡送出的值WebForm為True MVC為False,因此就算都使用VS,也會因為不同類型的專案導致不同的結果。

最簡單的處理方式就是直接導致

Thread.CurrentThread.Abort(new HttpAppication.CancelModuleException(false));

也就是先調用End()再令其
Response.End(); Thread.CurrentThread.Abort();

但是這會產生一些問題,就是當你用try ... catch包住它時,他會觸發ThreadAbortException錯誤,原因是因為他本來就會觸發ThreadAbortException,且不只Response.End(),Server.Transfer和Response.Redirect被呼叫時也會觸發(MS KB312629更新文件說明)

而KB同樣給出了做法
1.用HttpContext.Current.ApplicationInstance.CompleteRequest();取代Response.End()
2.如果使用Server.Transfer 用 Server.Execute代替
3.考慮使用Response.Redirect("...",false)

-------------------------------------------------------2021/03/11
不知道為何今天測試結果是會被中斷,當初確實搞這問題搞蠻久的.....G_G


參考:
https://blog.darkthread.net/blog/response-end-in-mvc/
https://www.cnblogs.com/v5wa/p/3165367.html
https://blog.darkthread.net/blog/threadabortexception-when-response-end
https://github.com/microsoft/referencesource
https://blog.miniasp.com/post/2010/01/03/ASPNET-MVC-Developer-Note-Part-14-Implement-HTTP-301-Moved-Permanentlyhttps:
//blog.miniasp.com/post/2010/01/03/ASPNET-MVC-Developer-Note-Part-14-Implement-HTTP-301-Moved-Permanently
https://dotblogs.com.tw/libtong/2017/10/03/105527

留言

這個網誌中的熱門文章

無法載入檔案或組件 'System.IO.Compression' 或其相依性的其中之一。

MongoDB 入門

javascript 更改屬性及創建標籤