.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 }