最近筆者開發網站的架構升級了,改用ASP.NET Core 5,Core的新特性一開始讓我很不習慣,在克服以後,沒想到跟上次一樣又是session功能讓我花了不少時間,不知道的讀者可以參考這篇。
鑑於上一篇的使用經驗,我已經習慣以物件的方式操作session,而不是用原生冗長的方式使用,但這次在嘗試時發現了一個問題,就是.Net 5不能用靜態的方式取得session,要使用DI獲得IHttpContextAccessor,在Startup.cs中加入DI設定,方式如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.Configure<GzipCompressionProviderOptions>(options => options.Level = System.IO.Compression.CompressionLevel.Fastest);
services.AddResponseCompression();
//加入以下兩行
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSession();
}
public void Configure(IApplicationBuilder app)
{
app.UseHttpsRedirection();
app.UseResponseCompression();
app.UseStaticFiles();
//加入下方這一行使用session
app.UseSession();
}
接著就可以在Controller中注入IHttpContextAccessor,原生的方式可以存取byte[], int, string基本型別,也可以自行擴充,寫入自訂物件,原理是使用json字串,但如果每次都這樣用,還是太辛苦了些,老問題還是key值的維護,打錯字可能無意間留下致命的bug。
public HomeController(IHttpContextAccessor httpContextAccessor)
{
httpContextAccessor.HttpContext.Session.Set(key, byte_array);
httpContextAccessor.HttpContext.Session.SetInt32(key, int_value);
httpContextAccessor.HttpContext.Session.SetString(key, string_value);
}
public static class SessionExtensions
{
public static void SetObject(this ISession session, string key, object 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);
}
}
為了以物件的方式使用,我嘗試將自訂的物件也用DI的方式,但始終取得httpContextAccessor為null,後來的折衷方式,就是使用靜態方法取得自訂物件
public class MySession
{
public MySession()
{
}
public bool IsLogin { get; set; } = false;
public int CompanyId { get; set; } = 0;
public static MySession Current(IHttpContextAccessor httpContextAccessor)
{
var mySession = httpContextAccessor.HttpContext.Session.GetObject<MySession>("__MySession__");
if (mySession == null)
{
mySession = new MySession();
httpContextAccessor.HttpContext.Session.SetObject("__MySession__", mySession);
}
return mySession;
}
}
按照上一次ASP.NET MVC的方式,但需要帶入HttpContextAccessor作為參數,還是可以達到一樣的效果,使用方式如下:
var mySession = MySession.Current(_httpContextAccessor);
mySession.IsLogin;
希望本篇對你有幫助
參考