当前位置:主页 > 软件编程 > .NET代码 >

ASP.NET Core中间件会话状态读写及生命周期示例

时间:2022-06-28 09:18:22 | 栏目:.NET代码 | 点击:

前言:

本文使用 .NET Core SDK 3.1 的版本。

1) 关于Http中的会话

2) 关于 ASP.NET Core 中的会话

一、配置会话中间件

配置基于内存的分布式缓存服务和会话服务,如需要将缓存放置于数据库可以参考微软官方文档

	public void ConfigureServices(IServiceCollection services)
	{
		// 添加基于内存的缓存服务,以供会话中间件来使用
        collection.AddDistributedMemoryCache();
        // 添加会话
        collection.AddSession();
	}

添加会话中间件

	public void Configure(IApplicationBuilder app)
	{
		// 引入会话中间件
		app.UseSession();
	}

二、会话状态的读写

写入Session

    ISession session = httpContext.Session;
    var sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
    session.SetString("SessionStartTime", sessionStartTime);

读取Session

    ISession session = httpContext.Session;
    session.TryGetValue("SessionStartTime", out var value);
    var sessionStartTime = Encoding.UTF8.GetString(value);

获取SessionId

    ISession session = httpContext.Session;
    session.TryGetValue("SessionStartTime", out var value);
    var sessionStartTime = Encoding.UTF8.GetString(value);

获取SessionKey

SessionKey 需要通过反射获取

    ISession session = httpContext.Session;
    var field = typeof(DistributedSession).GetTypeInfo()
        .GetField("_sessionKey", BindingFlags.Instance | BindingFlags.NonPublic);
    var sessionKey = field?.GetValue(session);

三、 示例的生命周期

这里准备了示例的代码:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/get", async httpContext =>
        {
            ISession session = httpContext.Session;
            string sessionStartTime;
            if (session.TryGetValue("SessionStartTime", out var value))
            {
                sessionStartTime = Encoding.UTF8.GetString(value);
            }
            else
            {
                sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
                session.SetString("SessionStartTime", sessionStartTime);
            }
            var field = typeof(DistributedSession).GetTypeInfo()
                .GetField("_sessionKey", BindingFlags.Instance | BindingFlags.NonPublic);
            var sessionKey = field?.GetValue(session);
            var responseText = $@"
                <html>
                <body>
                    <h1>Get Session</h1>
                    <ul>
                        <li>Session ID:{session.Id}</li>
                        <li>Session Key:{sessionKey}</li>
                        <li>Session Start Time:{sessionStartTime}</li>
                        <li>Current Time:{DateTime.Now:yyyy-MM-dd HH:mm:ss}</li>
                    </ul>
                </body>
                </html>";
            httpContext.Response.ContentType = "text/html";
            await httpContext.Response.WriteAsync(responseText);
        });
    });

清除浏览器中的 Cookie,然后刷新页面进入/get页面中,可以看到在新的网络请求中响应标头多了一个 set-cookie,这个set-cookie是被加密的SessionKey,还具有 httponly 的标签,以防止Cookie 的值被跨站读取。

默认请求下 Cookie 采用的路径是根路径

然后我们重新刷新页面,可以看到请求标头中多出一个 cookie,就是之前的 set-cookie,因为之前缓存被清除以后,第一次刷新标头多一个 set-cookie,相当于创建一个新的会话,当下一次发起请求就会带上 cookie。

四、其他

您可能感兴趣的文章:

相关文章