.net core Session会话

ASP.NET Core 应用在默认情况下会利用缓存来存储会话状态,并且默认采用的是分布式缓存。由于演示实例采用基于 Redis 数据库的分布式缓存,所以需要添加针对NuGet包“Microsoft.Extensions.Caching.Redis”的依赖。如下面的代码片段所示,我们调用 IServiceCollection 接口的 AddDistributedRedisCache 扩展方法添加了基于DistributedRedisCache 的服务注册。SessionMiddleware 中间件的注册则通过调用该 IApplication Builder接口的UseSession扩展方法来完成。

 1 using ConsoleApp7;
 2 using Microsoft.AspNetCore.Builder;
 3 using Microsoft.Extensions.Caching.Distributed;
 4 using Microsoft.Extensions.Caching.Memory;
 5 using Microsoft.Extensions.Caching.Redis;
 6 using Microsoft.Extensions.FileProviders;
 7 using Microsoft.Extensions.FileSystemGlobbing;
 8 using System.Diagnostics;
 9 using System.Text;
10 
11 Host.CreateDefaultBuilder().ConfigureWebHostDefaults(webHost =>
12 {
13     webHost.ConfigureServices(services =>
14     {
15         services.AddDistributedRedisCache(redis =>
16         {
17             redis.InstanceName = "session";
18             redis.Configuration = "192.168.0.190";
19 
20         });
21         services.AddSession();
22     });
23     webHost.Configure(config =>
24     {
25         config.UseSession();
26         config.Run((httpContext) =>
27         {
28             string test = httpContext.Session.GetString("test");
29             httpContext.Response.ContentType = "text/plain;charset=utf-8";
         httpContext.Session.LoadAsync();//首先异步加载会话状态以便后面操作Session
30 if (string.IsNullOrEmpty(test)) 31 { 32 test = "test" + DateTime.Now.ToString(); 33 httpContext.Session.SetString("test", test); 34 httpContext.Response.WriteAsync("没有取到session"); 35 } 36 else 37 { 38 httpContext.Response.WriteAsync(test); 39 } 40 return Task.CompletedTask; 41 }); 42 }); 43 44 }).Build().Run();

测试结果

 

如果有这个保存当前会话状态的Session Key,当会话状态在采用默认的分布式缓存进行存储时,整个数据字典(包括Key和Value)会采用预定义的格式序列化成字节数组,基于会话状态的缓存默认采用的是基于滑动时间的过期策略,默认采用的滑动过期时间为20分(12 000 000 000纳秒)

Session操作源码

 

  1 File: SessionExtensions.cs
  2 Web Access
  3 Project: src\src\Http\Http.Extensions\src\Microsoft.AspNetCore.Http.Extensions.csproj (Microsoft.AspNetCore.Http.Extensions)
 87 // Licensed to the .NET Foundation under one or more agreements.
 88 // The .NET Foundation licenses this file to you under the MIT license.
 89  
 90 using System.Text;
 91  
 92 namespace Microsoft.AspNetCore.Http;
 93  
 94 /// <summary>
 95 /// Extension methods for <see cref="ISession"/>.
 96 /// </summary>
 97 public static class SessionExtensions
 98 {
 99     /// <summary>
100     /// Sets an int value in the <see cref="ISession"/>.
101     /// </summary>
102     /// <param name="session">The <see cref="ISession"/>.</param>
103     /// <param name="key">The key to assign.</param>
104     /// <param name="value">The value to assign.</param>
105     public static void SetInt32(this ISession session, string key, int value)
106     {
107         var bytes = new byte[]
108         {
109                 (byte)(value >> 24),
110                 (byte)(0xFF & (value >> 16)),
111                 (byte)(0xFF & (value >> 8)),
112                 (byte)(0xFF & value)
113         };
114         session.Set(key, bytes);
115     }
116  
117     /// <summary>
118     /// Gets an int value from <see cref="ISession"/>.
119     /// </summary>
120     /// <param name="session">The <see cref="ISession"/>.</param>
121     /// <param name="key">The key to read.</param>
122     public static int? GetInt32(this ISession session, string key)
123     {
124         var data = session.Get(key);
125         if (data == null || data.Length < 4)
126         {
127             return null;
128         }
129         return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
130     }
131  
132     /// <summary>
133     /// Sets a <see cref="string"/> value in the <see cref="ISession"/>.
134     /// </summary>
135     /// <param name="session">The <see cref="ISession"/>.</param>
136     /// <param name="key">The key to assign.</param>
137     /// <param name="value">The value to assign.</param>
138     public static void SetString(this ISession session, string key, string value)
139     {
140         session.Set(key, Encoding.UTF8.GetBytes(value));
141     }
142  
143     /// <summary>
144     /// Gets a string value from <see cref="ISession"/>.
145     /// </summary>
146     /// <param name="session">The <see cref="ISession"/>.</param>
147     /// <param name="key">The key to read.</param>
148     public static string? GetString(this ISession session, string key)
149     {
150         var data = session.Get(key);
151         if (data == null)
152         {
153             return null;
154         }
155         return Encoding.UTF8.GetString(data);
156     }
157  
158     /// <summary>
159     /// Gets a byte-array value from <see cref="ISession"/>.
160     /// </summary>
161     /// <param name="session">The <see cref="ISession"/>.</param>
162     /// <param name="key">The key to read.</param>
163     public static byte[]? Get(this ISession session, string key)
164     {
165         session.TryGetValue(key, out var value);
166         return value;
167     }
168 }
169 Document OutlineProject ExplorerNamespace Explorer

 SessionOptions 源码

 66 // Licensed to the .NET Foundation under one or more agreements.
 67 // The .NET Foundation licenses this file to you under the MIT license.
 68  
 69 using Microsoft.AspNetCore.Http;
 70 using Microsoft.AspNetCore.Session;
 71  
 72 namespace Microsoft.AspNetCore.Builder;
 73  
 74 /// <summary>
 75 /// Represents the session state options for the application.
 76 /// </summary>
 77 public class SessionOptions
 78 {
 79     private CookieBuilder _cookieBuilder = new SessionCookieBuilder();
 80  
 81     /// <summary>
 82     /// Determines the settings used to create the cookie.
 83     /// </summary>
 84     /// <remarks>
 85     /// <list type="bullet">
 86     /// <item><description><see cref="CookieBuilder.Name"/> defaults to <see cref="SessionDefaults.CookieName"/>.</description></item>
 87     /// <item><description><see cref="CookieBuilder.Path"/> defaults to <see cref="SessionDefaults.CookiePath"/>.</description></item>
 88     /// <item><description><see cref="CookieBuilder.SameSite"/> defaults to <see cref="SameSiteMode.Lax"/>.</description></item>
 89     /// <item><description><see cref="CookieBuilder.HttpOnly"/> defaults to <c>true</c>.</description></item>
 90     /// <item><description><see cref="CookieBuilder.IsEssential"/> defaults to <c>false</c>.</description></item>
 91     /// </list>
 92     /// </remarks>
 93     public CookieBuilder Cookie
 94     {
 95         get => _cookieBuilder;
 96         set => _cookieBuilder = value ?? throw new ArgumentNullException(nameof(value));
 97     }
 98  
 99     /// <summary>
100     /// The IdleTimeout indicates how long the session can be idle before its contents are abandoned. Each session access
101     /// resets the timeout. Note this only applies to the content of the session, not the cookie.
102     /// </summary>
103     public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromMinutes(20);
104  
105     /// <summary>
106     /// The maximum amount of time allowed to load a session from the store or to commit it back to the store.
107     /// Note this may only apply to asynchronous operations. This timeout can be disabled using <see cref="Timeout.InfiniteTimeSpan"/>.
108     /// </summary>
109     public TimeSpan IOTimeout { get; set; } = TimeSpan.FromMinutes(1);
110  
111     private sealed class SessionCookieBuilder : CookieBuilder
112     {
113         public SessionCookieBuilder()
114         {
115             Name = SessionDefaults.CookieName;
116             Path = SessionDefaults.CookiePath;
117             SecurePolicy = CookieSecurePolicy.None;
118             SameSite = SameSiteMode.Lax;
119             HttpOnly = true;
120             // Session is considered non-essential as it's designed for ephemeral data.
121             IsEssential = false;
122         }
123  
124         public override TimeSpan? Expiration
125         {
126             get => null;
127             set => throw new InvalidOperationException(nameof(Expiration) + " cannot be set for the cookie defined by " + nameof(SessionOptions));
128         }
129     }
130 }

 

posted on 2023-02-20 10:49  是水饺不是水饺  阅读(85)  评论(0编辑  收藏  举报

导航