.ashx 處理程序中 context.Session 為 null,拋出 NullReferenceException,無法讀寫 Session 數據。
默認 IHttpHandler 不支持 Session,需顯式實現標記接口聲明需求。
using System.Web.SessionState;
public class MyHandler : IHttpHandler, IRequiresSessionState, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
{
// 現在可以正常訪問 Session
int userId = (int)context.Session["UserId"];
string userName = context.Session["UserName"]?.ToString();
// 業務邏輯...
context.Response.ContentType = "application/json";
context.Response.Write("{\"success\":true}");
}
public bool IsReusable => false;
}
| 接口 | 作用 | 場景 |
|---|---|---|
| IRequiresSessionState | 讀寫 Session(獲取鎖) | 需修改 Session 數據 |
| IReadOnlySessionState | 只讀 Session(無鎖,性能更好) | 僅讀取 Session 數據 |
<%@ WebHandler Language="C#" Class="ProductHandler" %>
using System;
using System.Web;
using System.Web.SessionState;
using Newtonsoft.Json;
public class ProductHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
string action = context.Request["action"];
string result = "";
try
{
switch (action)
{
case "getList":
// 讀取 Session 中的公司 ID
int companyId = (int)context.Session["CompanyId"];
var list = ProductService.GetList(companyId);
result = JsonConvert.SerializeObject(new { success = true, data = list });
break;
case "save":
// 寫入 Session 記錄操作日誌
var log = new OperationLog
{
UserId = (int)context.Session["UserId"],
Action = "SaveProduct",
Time = DateTime.Now
};
context.Session["LastLog"] = log;
result = "{\"success\":true}";
break;
}
}
catch (Exception ex)
{
result = $"{{\"success\":false,\"msg\":\"{ex.Message}\"}}";
}
context.Response.Write(result);
}
public bool IsReusable => false;
}
IReadOnlySessionState 避免鎖競爭<sessionState mode="InProc"> 配置正確mode="StateServer" 或 "SQLServer" 共享 Session// Startup.cs
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
});
// Middleware 順序重要
app.UseSession();
// Handler/Controller 中
HttpContext.Session.SetInt32("UserId", 123);
int? userId = HttpContext.Session.GetInt32("UserId");
一行接口聲明解決 ASHX Session 無法訪問問題,理解背後機制才能舉一反三。