asp.net core web api 默认不启用 session,需同时注册 adddistributedrediscache、addsession 并调用 usesession(在 userouting 后、useendpoints 前),且 cookie.isessential = true;session 数据以加密 blob 存于 redis 字符串键 .aspnetcore.session:{sessionid} 中,应始终通过 isession 操作。

ASP.NET Core Web API 默认不带 Session 支持,直接调用 HttpContext.Session 会抛出 NullReferenceException —— 因为 Session 中间件根本没注册,更别说连 Redis 了。
为什么 Web API 项目里 HttpContext.Session 是 null?
Web API 模板默认不启用 Session,它被设计为无状态服务。即使你装了 Microsoft.Extensions.Caching.Redis,也只提供了分布式缓存能力,不是 Session 功能本身。
Session 的完整链路需要三样东西同时到位:
-
AddDistributedRedisCache():注册 Redis 缓存提供者(仅提供底层存储) -
AddSession():启用 Session 中间件,并指定使用哪个分布式缓存 -
UseSession():在请求管道中插入 Session 中间件(必须在UseRouting之后、UseEndpoints之前)
漏掉任意一个,HttpContext.Session 就是 null。常见错误是只配了 Redis 缓存,忘了调 AddSession 和 UseSession。
AddDistributedRedisCache 和 AddSession 怎么配才生效?
在 Program.cs(.NET 6+)里顺序不能错:
var builder = WebApplication.CreateBuilder(args);
// 1. 注册 Redis 分布式缓存(必须先于 Session)
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "session_";
});
// 2. 启用 Session(关键!指定使用上面注册的 Redis 缓存)
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true; // 否则 UseSession 可能跳过
});
var app = builder.Build();
// 3. 使用 Session(必须在 UseRouting 之后、UseEndpoints 之前)
app.UseRouting();
app.UseSession(); // ← 这行不能少,也不能放错位置
app.UseAuthorization();
app.MapControllers();
注意点:
-
options.Cookie.IsEssential = true是硬性要求,否则UseSession会静默跳过 Cookie 初始化 -
IdleTimeout控制的是“不活动超时”,不是绝对 TTL;Redis 中实际键的过期时间由 Session 中间件自动续期管理 - 不要手动调用
ISession.SetString前检查HttpContext.Session != null—— 如果配置正确,它一定不为 null;为空说明配置失败,该查中间件顺序
Session ID 是怎么和 Redis 键关联的?
ASP.NET Core Session 不把整个对象序列化后塞进一个 Redis key,而是拆成两层:
- 主键格式:
.AspNetCore.Session:{sessionId}(由InstanceName+ 默认前缀拼成) - 值是二进制 blob,内容是经过加密、压缩、序列化的 Session 字典(含所有
SetString/SetInt32存的数据)
这意味着:
- 你无法用
redis-cli直接GET看清内容(它是加密的,默认用 Data Protection 加密) - 不能用
HGETALL查字段 —— 它不是 Hash 类型,是 String 类型的 blob - 如果想调试,可临时关闭加密:
services.AddDataProtection().DisableAutomaticKeyGeneration();(仅开发环境)
别试图绕过 ISession 接口直接操作 Redis —— Session 中间件内部有并发控制、脏检查、过期刷新逻辑,手写容易丢数据或破坏一致性。
跨域或非浏览器客户端怎么传 Session ID?
Session 依赖 Cookie,而 Cookie 默认受同源策略限制。如果你的前端是 Vue/React 独立域名,或移动端 App 调用 Web API:
- 浏览器端:必须让前端发请求时带上
credentials: 'include',且后端CorsPolicy开启AllowCredentials = true,并显式指定WithOrigins("https://your-frontend.com")(不能用*) - 非浏览器客户端(如 App):Cookie 很难可靠传递,建议改用 Token 方案 —— 登录成功后,把用户标识写入 Redis(key 为 token,value 为用户信息),再把 token 通过响应体返回;后续请求由客户端在 Header(如
Authorization: Bearer xxx)里传 token,服务端自己查 Redis 验证
强行让 App 模拟 Cookie 行为,不仅复杂,还容易因 Cookie 存储机制差异导致失效 —— 这不是 Session 的设计场景。
最常被忽略的一点:Session ID 的生成和传输完全由框架控制,你不需要、也不应该自己生成或解析 ASP.NET_SessionId Cookie。所有操作都应通过 ISession 接口进行,哪怕只是存个字符串。一旦开始混用 IDistributedCache 直接操作 Redis,就等于绕过了 Session 的生命周期管理,超时、续期、并发安全全得自己兜底。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











