開發環境(IIS 7/7.5/8/10)一切正常,部署至 IIS 6 後,頁面重新整理時頻繁出現「AJAX 用戶端架構無法載入」錯誤(Sys.WebForms.PageRequestManagerParserErrorException 或 ScriptResource.axd/WebResource.axd 載入失敗)。
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
string oldToken = Session["token"].ToString(); // 直接存取 Session,未判斷 null
}
Application_AcquireRequestState 在 ASP.NET 取得與目前要求關聯的 Session 狀態時觸發。ScriptResource.axd、WebResource.axd 等靜態資源請求,在 IIS 6 下會經過完整 ASP.NET 管線,因此每一個 .axd 請求都會觸發此事件。一個頁面若引用多個 Script/樣式,就會觸發多次。Session["token"] 為 null,呼叫 .ToString() 拋出 NullReferenceException,中斷回應串流,造成 AJAX 載入失敗。protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (Session != null && Session["token"] != null)
{
string oldToken = Session["token"].ToString();
// 後續邏輯...
}
}
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
// 排除 AJAX 資源請求、Web Service 請求
string url = context.Request.Url.AbsolutePath.ToLower();
if (url.EndsWith(".axd") || url.EndsWith(".asmx"))
return;
// 正常頁面請求才處理 Session
if (context.Session != null && context.Session["token"] != null)
{
string oldToken = context.Session["token"].ToString();
// 後續邏輯...
}
}
若邏輯必須在 Session 確定可用之後執行,可改掛在 Application_PostAcquireRequestState,此時 Session 已確保可用(若啟用 Session)。但仍建議搭配方案二過濾 .axd 請求。
| 特性 | IIS 6 (Classic Mode) | IIS 7+ (Integrated Mode) |
|---|---|---|
| .axd 請求是否經過 Managed Pipeline | 是(需 wildcard mapping) | 否(原生模組處理,不進入 Managed Handler) |
| Application_AcquireRequestState 觸發次數 | 每個 .axd 請求各觸發一次 | 僅頁面請求觸發 |
| Session 可用性 | .axd 請求無 Session | .axd 請求不進入此事件 |
Global.asax 任何事件中存取 Session 前,務必先判斷 `Context.Session != null`。.axd、.asmx、.ashx 等特殊副檔名請求,盡早 return,避免不必要的 Session 存取與邏輯執行。web.config 設定 <httpModules> 而非 <modules>,並確認 wildcard mapping 正確。