[ASP.NET 5]又一篇Session的使用

最近筆者開發網站的架構升級了,改用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;

希望本篇對你有幫助

參考

對「[ASP.NET 5]又一篇Session的使用」的一則回應

Add yours

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

Create a website or blog at WordPress.com

向上 ↑

%d 位部落客按了讚: