在 ASP.NET 應用程式執行期間,若程式碼對**應用程式虛擬目錄底下**的資料夾進行建立、刪除、重命名或移動操作,會導致 **AppDomain 重啟**,造成 In-Process Session 遺失 (Session 變成 null),使用者被迫重新登入。
FileChangesMonitor 監視虛擬目錄下的檔案系統變更。HttpRuntime.UnloadAppDomain(),導致應用程式域卸載重載。| 方案 | 原理 | 優點 | 缺點 |
|---|---|---|---|
| StateServer (Out-of-Process) | Session 由獨立 Windows 服務 aspnet_state.exe 管理,跨 AppDomain 共享 |
部署簡單、效能佳、支援 Web Farm | 序列化開銷、需啟動服務、單點故障 |
| SQLServer | Session 持久化至 SQL Server 資料庫 | 高可用、支援叢集、資料持久 | 延遲最高、需授權、序列化限制 |
| Custom Cookie + Rehydrate | 關鍵識別資訊 (UserId) 寫入 Cookie,Session 遺失時自動重建 | 零基礎建設成本、彈性高 | 需自行實作、安全性須自行把關 |
services.msc → ASP.NET State Service → 啟動類型設為「自動」並啟動。web.config:
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
cookieless="false"
timeout="40" />
※ 預設埠號為 42424,非文中 1314 (可能為筆誤)。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters]
"AllowRemoteConnection"=dword:00000001
[Serializable] 屬性。// 原結構 (會觸發 AppDomain 重啟)
/WebApp/Uploads/Temp/ ← 程式碼在此建立/刪除資料夾
// 調整後 (不觸發監視)
/Data/Uploads/Temp/ ← 位於 Web 應用程式根目錄之外
// 程式碼使用绝對路徑或設定檔路徑存取
此法從根源避免 FileChangesMonitor 偵測到變更,最乾淨但需調整部署架構。
// 登入成功時
Session["UserId"] = user.Id;
Response.Cookies["AuthToken"].Value = user.Id.ToString(); // 或加密 Token
Response.Cookies["AuthToken"].Expires = DateTime.Now.AddDays(30);
// Global.asax 或 BasePage.PreLoad
if (Session["UserId"] == null && Request.Cookies["AuthToken"] != null)
{
string userId = Request.Cookies["AuthToken"].Value;
// 驗證 Token 有效性、查詢使用者資料
Session["UserId"] = userId;
Session["UserName"] = GetUserName(userId);
// ... 重建其他 Session 變數
}