筆者因工作因素,不得不碰Microsoft MVC 3。雖然開發方便,不過他隱含的一些奇怪的Bug也不少。
身為一個網站開發人員,時常會用到Cookie與Session。奇怪的點就在於MS Visual Studio 2010在開發MVC 3時,有時候會為了某些奇怪因素,重新啟動你開發的Application。
目前普遍知道的重新啟動事件,可能會於以下情形發生:
- 從應用程式的 Bin 資料夾中加入、修改或刪除組件。
- 從 App_GlobalResources 或 App_LocalResources 資料夾中加入、修改或刪除當地語系化資源。
- 加入、修改或刪除應用程式的 Global.asax 檔。
- 在 App_Code 目錄中加入、修改或刪除原始程式碼檔。
- 加入、修改或刪除設定檔組態。
- 在 App_WebReferences 目錄中加入、修改或刪除 Web 服務參考。
- 加入、修改或刪除應用程式的 Web.config 檔。
- 防毒軟體剛好掃到Webconfig檔
然而,筆者最近發現兩個更奇怪的重新啟動狀況!
- Application restarts on directory delete in ASP.net
- 檔案上傳後,在該Action內直接return RedirectToAction() ;
開發MVC 3 or ASP.NET網站人員應該都知道,在SessionState為InProc的設定下,任何重新啟動( or Application_start函數的呼叫),將導致Session消失。
很不巧地,筆者剛好遇到上述第2種狀況,導致Session消失,Debug 10個小時才抓到此嚴重錯誤。
其實上面第 2種狀況,應該算是「 Bin 資料夾中加入、修改或刪除組件」,從下面程式碼便可知一二:
其實上面第 2種狀況,應該算是「 Bin 資料夾中加入、修改或刪除組件」,從下面程式碼便可知一二:
public ActionResult Access()
{
// 取出剛剛上傳的檔名,這邊會發現取不到值
string fileName = TempData["upfile"].ToString();
/*
* 處理的程式區段
*/
return View();
}
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
//檢查是否有檔案上傳,有的話存檔
if (file !=null && file.ContentLength > 0)
{
//放在執行檔目錄中Upload目錄底下
string savedName = "./Upload/" + file.FileName;
file.SaveAs(savedName);
TempData["upfile"]=file.FileName;
}
return RedirectToAction("Access");
}
從上述可知,由於我在檔案上傳時,”增加”了bin資料夾下的組件,導致Application_start()函數再次啟動,使得我的Session就這麼消失了。
為了避免這個錯誤一再重演,建議將Session State設定為StateServer或是SQL Server模式。
將Session State設定為State Server的方法,可看這篇「如何讓 ASP.NET 使用 Session 資料時不要再自動消失」,主要兩個步驟:
1. 啟動 aspnet_state.exe (ASP.NET State Service)
2. 在Web.config中,加入以下這段設定:
1. 啟動 aspnet_state.exe (ASP.NET State Service)
2. 在Web.config中,加入以下這段設定:
<configuration>
<system.web>
<sessionState mode=”StateServer”
stateConnectionString=”tcpip=localhost:42424″
cookieless=”false”
timeout=”20″/>
</system.web>
</configuration>
需要注意設定的Web.config檔案的出處。(不知道為什麼,筆者的View資料夾下剛好也有Web.config,若手誤設定到這個,執行會錯誤喔!)
為了追求開發出來的程式不因Application重新啟動而造成不穩定狀況 (例如:筆者遇到的檔案上傳導致無法儲存Session的問題,也是透過部署的方式,立刻解決!)。
我們通常會需要用到部署,至於設定部署功能,請跟著筆者這樣子做:
- 請先安裝好IIS 6/7
- 若是使用ASP.NET 4.0,ASP.NET 4.0的安裝程式,不會連同IIS一起設定,因此,請按照此方法設定。
- 從IIS中,設定好網站目錄 or 虛擬目錄。
- 設定單鍵發行功能,方法請看如何使用 Visual Studio 2010 的「單鍵發行」功能 (MsDeploy)
另一個可能發生的問題,則是在負載平衡的 Web 伺服陣列環境執行 ASP.NET Web 應用程式時,如果使用 SqlServer 或 StateServer 工作階段模式,工作階段狀態可能會遺失。
解決辦法在微軟的「PRB:如果您使用 SqlServer 或 StateServer 工作階段模式,Web 伺服陣列中的工作階段狀態會遺失」,剛好遇到這類問題的使用者,可以看一看。
Reference
解決辦法在微軟的「PRB:如果您使用 SqlServer 或 StateServer 工作階段模式,Web 伺服陣列中的工作階段狀態會遺失」,剛好遇到這類問題的使用者,可以看一看。
Reference