一、配置回話狀態
Microsoft.AspNetCore.App metapackage 中包含的 Microsoft.AspNetCore.Session 包提供中間件來管理會話狀態。 若要啟用會話中間件,Startup
必須包含:
- 任一 IDistributedCache 內存緩存。
IDistributedCache
實現用作會話后備存儲。 有關詳細信息,請參閱 ASP.NET Core 中的分布式緩存。 - 對
ConfigureServices
中 AddSession 的調用。 - 對
Configure
中 UseSession 的調用。
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddDistributedMemoryCache(); services.AddSession(options => { // Set a short timeout for easy testing. options.IdleTimeout = TimeSpan.FromSeconds(10); options.Cookie.HttpOnly = true; // Make the session cookie essential options.Cookie.IsEssential = true; }); services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseSession(); app.UseHttpContextItemsMiddleware(); app.UseMvc(); } }
中間件的順序很重要。 在前面的示例中,在 UseMvc
之后調用 UseSession
時會發生 InvalidOperationException
異常。 有關詳細信息,請參閱中間件排序。
配置會話狀態后,HttpContext.Session 可用。
調用 UseSession
以前無法訪問 HttpContext.Session
。
在應用已經開始寫入到響應流之后,不能創建有新會話 Cookie 的新會話。 此異常記錄在 Web 服務器日志中但不顯示在瀏覽器中。
二、以異步方式加載會話狀態
只有在 TryGetValue、Set 或 Remove 方法之前顯式調用 ISession.LoadAsync 方法,ASP.NET Core 中的默認會話提供程序才會從基礎 IDistributedCache 后備存儲以異步方式加載會話記錄。 如果未先調用 LoadAsync
,則會同步加載基礎會話記錄,這可能對性能產生大規模影響。
若要讓應用強制實施此模式,如果未在 TryGetValue
、Set
或 Remove
之前調用 LoadAsync
方法,那么使用引起異常的版本包裝 DistributedSessionStore 和 DistributedSession 實現。 在服務容器中注冊的已包裝的版本。
三、會話選項
若要替代會話默認值,請使用 SessionOptions。
選項 | 說明 |
---|---|
Cookie | 確定用於創建 Cookie 的設置。 名稱默認為 SessionDefaults.CookieName (.AspNetCore.Session )。 路徑默認為 SessionDefaults.CookiePath (/ )。 SameSite 默認為 SameSiteMode.Lax (1 )。 HttpOnly 默認為 true 。 IsEssential 默認為 false 。 |
IdleTimeout | IdleTimeout 顯示放棄其內容前,內容可以空閑多長時間。 每個會話訪問都會重置超時。 此設置僅適用於會話內容,不適用於 Cookie。 默認為 20 分鍾。 |
IOTimeout | 允許從存儲加載會話或者將其提交回存儲的最大時長。 此設置可能僅適用於異步操作。 可以使用 InfiniteTimeSpan 禁用超時。 默認值為 1 分鍾。 |
會話使用 Cookie 跟蹤和標識來自單個瀏覽器的請求。 默認情況下,此 Cookie 名為 .AspNetCore.Session
,並使用路徑 /
。 由於 Cookie 默認值不指定域,因此它不提供頁上的客戶端腳本(因為 HttpOnly 默認為 true
)。
若要替換 Cookie 會話默認值,請使用 SessionOptions
:
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDistributedMemoryCache(); services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSession(options => { options.Cookie.Name = ".AdventureWorks.Session"; options.IdleTimeout = TimeSpan.FromSeconds(10); options.Cookie.IsEssential = true; }); }
應用使用 IdleTimeout 屬性確定放棄服務器緩存中的內容前,內容可以空閑多長時間。 此屬性獨立於 Cookie 到期時間。 通過會話中間件傳遞的每個請求都會重置超時。
會話狀態為“非鎖定” 。 如果兩個請求同時嘗試修改同一會話的內容,則后一個請求替代前一個請求。 Session
是作為一個連貫會話實現的,這意味着所有內容都存儲在一起 。 兩個請求試圖修改不同的會話值時,后一個請求可能替代前一個做出的會話更改。
四、設置和獲取會話值
使用 HttpContext.Session 從 Razor Pages PageModel 類或 MVC 控制器類訪問會話狀態。 此屬性是 ISession 實現。
ISession
實現提供用於設置和檢索整數和字符串值的若干擴展方法。 項目引用 Microsoft.AspNetCore.Http.Extensions 包時,擴展方法位於 Microsoft.AspNetCore.Http 命名空間中(添加 using Microsoft.AspNetCore.Http;
語句獲取對擴展方法的訪問權限)。 這兩個包均包括在 Microsoft.AspNetCore.App 元包中。
ISession
擴展方法:
- Get(ISession, String)
- GetInt32(ISession, String)
- GetString(ISession, String)
- SetInt32(ISession, String, Int32)
- SetString(ISession, String, String)
以下示例在 Razor Pages 頁中檢索 IndexModel.SessionKeyName
鍵(示例應用中的 _Name
)的會話值:
@page
@using Microsoft.AspNetCore.Http
@model IndexModel
...
Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)
更多:
Asp.net Core CacheHelper 通用緩存幫助類