webapi和mvc的區別,Response.End()在Webform和ASP.NET MVC下的表現差異

 2023-11-18 阅读 20 评论 0

摘要:前幾天在博問中看到一個問題——Response.End()后,是否停止執行?MVC與WebForm不一致。看到LZ的描述后,雖然奇怪于為何用Response.End()而不用return方式去控制流程,但基于自己以往的認識,還是回答了說需要return。 因為以往的開發過程中&

前幾天在博問中看到一個問題——Response.End()后,是否停止執行?MVC與WebForm不一致。看到LZ的描述后,雖然奇怪于為何用Response.End()而不用return方式去控制流程,但基于自己以往的認識,還是回答了說需要return。

因為以往的開發過程中,雖然沒有用過Response.End()的方式像LZ所說地那樣“方便地從多層調用中退出”,但是始終是認為Response.End()是不能終止其后代碼執行的,思維路線大概是:Response.End()只是結束了HTTP返回流的寫入,但是代碼依然沒有return啊,例如Page_Load中使用了Response.End(),但是這個方法并沒有被跳出/終止。

之后LZ編輯了問題,繼續提到了問題沒有解決,又附帶了偽代碼希望大家幫忙改進書寫方式。直到此時,由于自己的思維慣性,我依然我沒有去寫DEMO去驗證對比webform和mvc下的Response.End(),簡單地用主動throw new Exception的方式寫出了MVC下“好看一點”的代碼。

之后在回復中,LZ再次重復了Response.End()確實在webform和mvc中存在差異,我抱著試一試地心態測了一個療程。真的有點吃驚,Reponse.End()在webfrom和ASP.NET MVC下的表現確實是不同的!

webapi和mvc的區別。ASP.NET MVC代碼:

public ActionResult Index()
{Method0();Method1();Method2();Response.Write("All methods success.");return View("I don't think so.");
}private void Method0()
{Debug.WriteLine("Method 0 process...");bool flag = true;if (!flag){Response.Write("Method 0 failure.");Response.End();}
}private void Method1()
{Debug.WriteLine("Method 1 process...");bool flag = false;if (!flag){Response.Write("Method 1 failure.");Response.End();}
}private void Method2()
{Debug.WriteLine("Method 2 process...");bool flag = false;if (!flag){Response.Write("Method 2 failure.");Response.End();}
}

web頁面顯示:

image

調試信息輸出:

QQ圖片20130715162800

webform和winform的區別?Response.End()后的代碼繼續執行,這與之前的認識是沒有出入的,接下來看webform。

Webform代碼:

protected void Page_Load(object sender, EventArgs e)
{Method0();Method1();Method2();Response.Write("All methods success.");
}private void Method0()
{Debug.WriteLine("Method 0 process...");bool flag = true;if (!flag){HttpContext.Current.Response.Write("Method 0 failure.");System.Web.HttpContext.Current.Response.End();}
}private void Method1()
{Debug.WriteLine("Method 1 process...");bool flag = false;if (!flag){HttpContext.Current.Response.Write("Method 1 failure.");System.Web.HttpContext.Current.Response.End();}
}private void Method2()
{Debug.WriteLine("Method 2 process...");bool flag = true;if (!flag){HttpContext.Current.Response.Write("Method 2 failure.");System.Web.HttpContext.Current.Response.End();}
}

web頁面輸出:

image

調試信息:

Spring MVC的工作原理是怎樣的?image

web頁面的輸出一致,調試窗口那里可是大不一樣。webform并未接著執行Response.End()后的代碼,因為拋出了一個ThreadAbortException異常。這時候,我首先想到的是ASP.NET MVC下的Response對象類型是否和ASP.NET不同,導致他們的處理方式不同。

后來發現雖然ASP.NET MVC中的Response類型是HttpResponseBase,但是顯式地去調用System.Web.Context.Current.Response.End()結果依舊。通過Reflector查看ASP.NET MVC下HttpResponseBase的實現類HttpResponseWrapper,End方法的實現如圖,this_httpResponse是HttpResponse的私有變量。

image

查到這兒思路一度中斷,只好回頭去對比調試信息中的表現,從ThreadAbortException這個異常入手,發現在ASP.NET MVC中先調用Response.End(),再調用Thread.CurrentThread.Abort()可以達到webform下調用Response.End()的效果。當然其他異常也能模擬,但是此時發現了一個小問題,就是拋出普通異常的時候和拋出ThreadAbortException異常略有不同

webform和mvc的區別,普通異常的彈出窗口:

image

調試信息輸出:

image

ThreadAbortException異常沒有彈出那個窗口,調試信息中也多了一條信息。

前端foreach用法、image

是由于ThreadAbortException是SystemException(系統異常)被特殊對待了嗎?

這只是一個衍生出來的疑問,繼續剛才的問題,用ThreadAbortException和ASP.NET MVC作為關鍵字去google搜索,在Will保哥的博客中得到了解答!

具體可以參見這篇博客下的評論和另一篇博客。

image

mvc請求流程,經過保哥的指點,通過Reflector去查看源碼,證實了是_timeoutState的作用。

HttpResponse.End中代碼:

image

IsInCancellablePeriod屬性:

image

問題得到了解決!~但是我還有一個小疑問,也就是從Reflector中看到End方法的源碼,IsInCancellablePeriod是bool類型,但是卻判斷是否等于null。這怎么也是不合適的吧,是Reflector的解析錯誤還是其他原因導致的呢?

image

轉載于:https://www.cnblogs.com/v5wa/p/3165367.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/175513.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息