[译]ASP.NET Core 2.0 会话状态

时间:2023-12-27 17:59:25

问题

如何在ASP.NET Core 2.0中存储会话状态?

答案

创建一个空项目,修改Startup类的ConfigureServices()方法,添加会话状态服务和它后台的存储服务:

public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache();
services.AddSession();
}

在Configure()中添加会话中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSession(); app.Use(async (context, next) =>
{
context.Session.SetString("GreetingMessage", "Hello Session State");
await next();
}); app.Run(async (context) =>
{
var message = context.Session.GetString("GreetingMessage");
await context.Response.WriteAsync($"{message}");
});
}

运行,此时页面效果:

[译]ASP.NET Core 2.0 会话状态

讨论

我们可以使用会话状态在同一个浏览器不同HTTP请求之间共享数据。这个数据是存储在缓存中的(也就是IDistributedCache实现),并且可以通过HttpContext.Session属性来访问。

为了关联不同的HTTP请求,一个Cookie被存储到浏览器端,它的默认名称是.AspNetCore.Session.

在配置会话状态服务时,我们可以设置各种属性:

1. HttpOnly:设置Cookie是否可以通过JavaScript访问。缺省值是true,也就是说在客户端不能通过脚本访问。

2. Name:用来覆盖缺省的Cookie名称。

3. SecurePolicy:是否只能通过HTTPS请求来传输Cookie信息。

4. IdelTimeout:设置会话的过期时间,每一个后续的请求都会重置这个时间。缺省值是20分钟。

public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache(); services.AddSession(options => {
options.Cookie.HttpOnly = true;
options.Cookie.Name = ".Sanshi.Session";
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.IdleTimeout = TimeSpan.FromMinutes(10);
});
}

下面我们对比下,默认的Cookie:

[译]ASP.NET Core 2.0 会话状态

配置Session的Cookie.Name属性之后:

[译]ASP.NET Core 2.0 会话状态

存储对象

HttpContext.Session(实现了ISession接口)没有提供保存复杂对象的方法,然而我们可以通过序列化对象为字符串来实现这个功能:

public static class SessionExtensions
{
public static void SetObject<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
} public static T GetObject<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
}

JsonConvert是Newtonsoft.Json库的一个静态类,可以方便的在.Net类型和JSON类型之间转换,VS可以快速添加:

[译]ASP.NET Core 2.0 会话状态

接下来,我们就可以使用这些扩展方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSession(); app.Use(async (context, next) =>
{
context.Session.SetObject("CurrentUser",
new UserInfo { Username = "James", Email = "james@bond.com" });
await next();
}); app.Run(async (context) =>
{
var user = context.Session.GetObject<UserInfo>("CurrentUser");
await context.Response.WriteAsync($"{user.Username}, {user.Email}");
});
}  

运行,此时页面显示:

[译]ASP.NET Core 2.0 会话状态

通过依赖注入访问

我们可以通过构造函数注入方式来使用会话状态(IHttpContextAccessor),然后通过这个接口来访问HttpContext属性。

源代码下载

原文:https://tahirnaushad.com/2017/08/18/asp-net-core-session-state/