首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 虛擬目錄下刪除/修改資料夾導致 Session 遺失的根因與三種解決方案

     編輯:ASP.NET 基礎

現象描述

在 ASP.NET 應用程式執行期間,若程式碼對**應用程式虛擬目錄底下**的資料夾進行建立、刪除、重命名或移動操作,會導致 **AppDomain 重啟**,造成 In-Process Session 遺失 (Session 變成 null),使用者被迫重新登入。

根因分析

  • ASP.NET 透過 FileChangesMonitor 監視虛擬目錄下的檔案系統變更。
  • 目錄結構變更會觸發 HttpRuntime.UnloadAppDomain(),導致應用程式域卸載重載。
  • In-Proc Session 儲存在記憶體中,AppDomain 重啟即清空。

三種主流解決方案比較

方案原理優點缺點
StateServer (Out-of-Process) Session 由獨立 Windows 服務 aspnet_state.exe 管理,跨 AppDomain 共享 部署簡單、效能佳、支援 Web Farm 序列化開銷、需啟動服務、單點故障
SQLServer Session 持久化至 SQL Server 資料庫 高可用、支援叢集、資料持久 延遲最高、需授權、序列化限制
Custom Cookie + Rehydrate 關鍵識別資訊 (UserId) 寫入 Cookie,Session 遺失時自動重建 零基礎建設成本、彈性高 需自行實作、安全性須自行把關

方案一:StateServer 完整設定步驟 (推薦中小型專案)

  1. 啟動服務:services.msc → ASP.NET State Service → 啟動類型設為「自動」並啟動。
  2. 修改 web.config:
    <sessionState
        mode="StateServer"
        stateConnectionString="tcpip=127.0.0.1:42424"
        cookieless="false"
        timeout="40" />
    

    ※ 預設埠號為 42424,非文中 1314 (可能為筆誤)。

  3. 跨機器存取需開啟登錄鍵值:
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters]
    "AllowRemoteConnection"=dword:00000001
    
  4. ⚠ 重要:放入 Session 的自訂類別必須標記 [Serializable] 屬性。

方案二:將操作目錄移出虛擬目錄 (架構層面根治)

// 原結構 (會觸發 AppDomain 重啟)
/WebApp/Uploads/Temp/   ← 程式碼在此建立/刪除資料夾

// 調整後 (不觸發監視)
/Data/Uploads/Temp/     ← 位於 Web 應用程式根目錄之外
// 程式碼使用绝對路徑或設定檔路徑存取

此法從根源避免 FileChangesMonitor 偵測到變更,最乾淨但需調整部署架構。

方案三:Cookie 備援重建 Session (零設定快速修補)

// 登入成功時
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 變數
}

總結建議

  1. 新專案:直接採用 StateServer 或 SQLServer,並規劃 Session 物件可序列化。
  2. 既有專案快速止血:將異動目錄移出虛擬目錄,或加入 Cookie 重建機制。
  3. 避免踩坑:切勿在虛擬目錄下動態產生/編譯程式碼 (如 Razor 編譯、動態 DLL) —— 同樣會觸發重啟。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved