一、配置回话状态
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)
更多: