問題
如何在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}");
});
}
運行,此時頁面效果:

討論
我們可以使用會話狀態在同一個瀏覽器不同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:

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

存儲對象
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可以快速添加:

接下來,我們就可以使用這些擴展方法:
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}");
});
}
運行,此時頁面顯示:

通過依賴注入訪問
我們可以通過構造函數注入方式來使用會話狀態(IHttpContextAccessor),然后通過這個接口來訪問HttpContext屬性。
源代碼下載
原文:https://tahirnaushad.com/2017/08/18/asp-net-core-session-state/
文章列表
留言列表
