iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 16
1
Modern Web

.Net Core 網站開發 101系列 第 16

App States 工作階段與應用程式狀態 - 1/2

由於 HTTP 是無狀態的通訊協定,如果沒有額外處理,每次請求都會是獨立的,沒辦法保留來自客戶端的資料。今天會介紹要怎麼在應用程式中儲存或暫存資料跟狀態。

狀態管理

開發人員可以由幾個面向來判斷需要使用哪種狀態管理的方式:

  • 資料需要儲存多久?
  • 資料大小?
  • 資料格式?
  • 資料是否可以序列化?
  • 是否為敏感資料?

ASP.NET Core 框架中好幾種方式來管理狀態,包括:

  • Cookie
  • Session
  • TempData
  • Query String & Hidden Feilds
  • HttpContext.Items
  • 快取
  • 依賴注入

Cookie

Cookie 以類似 key-value 的資料結構儲存在客戶端,會隨著每次請求被傳送到伺服器端,所以當 Cookie 數量增加或儲存的值長度較大的時候,請求的封包會隨之變大。由於在客戶端可以新增、修改或刪除 Cookie,不建議將敏感資料以這個方式儲存,或者要加密後再儲存。在 Controller 中以下列程式來讀寫 Cookie

public class ApplicationStatesController : Controller
{
    public IActionResult Cookie()
    {
        Request.Cookies.TryGetValue("SampleCookie", out var cookieValue);

        // 把取出的值寫進 log
        _logger.LogDebug(cookieValue);

        Response.Cookies.Append("SampleCookie", Guid.NewGuid().ToString(), new CookieOptions
        {
            MaxAge = TimeSpan.FromMinutes(30)
        });

        return new EmptyResult();
    }
}

Response.Cookies.Append 的第三個參數是可選的 CookieOptions 類別,用來設定相關參數。範例中是將 SampleCookie 的值設定為 30 分鐘後過期。執行後可以在瀏覽器的開發工具中看到當前網域的所有 cookie。
https://ithelp.ithome.com.tw/upload/images/20181030/20107875u12rEtkYtE.png

Session

在其他地方可能會翻譯成「工作階段」。Session 是將資料存在伺服器的記憶體或資料庫中,再把一個唯一識別值 (id) 寫到 Cookie 中,並透過此 id 來存取資料。

要使用 Session 的設定比 Cookie 麻煩很多,需要在 Startup.cs 中設定:

  • 實作 Session 儲存區的 IDistributedCache。目前提供記憶體資料庫Redis 三種儲存方式。
  • Startup.ConfigureServices 中呼叫 AddSession
  • Startup.Configure 中呼叫 UseSession
public class Startup
{
    public void ConfigureServices(IServiceCollection services){
        // ...other services configurations
        services.AddDistributedMemoryCache();
        services.AddSession();
    }

    public void Configure(IApplicationBuilder app)
    {
        // ...other middlewares registrations
        app.UseSession();
        // ...other middlewares registrations
    }
}

需要特別注意加入中介層的順序,如果在 UseSession 之前先呼叫 UseMvc,就沒辦法在 MVC 架構中的程式使用 Session。設定完成後就可在應用程式中用 SessionExtensions 提供的各種方法來讀寫 Session 值。由於 Session 儲存在 IDistributedCache 中,資料都需要轉換成 byte[],只有另外提供 stringint32 的介面做讀寫。如果要儲存物件,就需要序列化成字串來處理。官方文件中有提供序列化的擴充方法可以參考:

public static class SessionSerializerExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);

        return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
    }
}

在程式中讀寫的方式:

public IActionResult Session()
{
    var sessionValue = HttpContext.Session.GetString("SampleSession");

    HttpContext.Session.SetInt32("Year", 2018);

    HttpContext.Session.Set("CurrentDate", DateTime.Now);

    return new EmptyResult();
}

參考資料


今天就先講到這吧~明天再來談談其他儲存狀態的方式


上一篇
番外篇 - NLog
下一篇
App States 工作階段與應用程式狀態 - 2/2
系列文
.Net Core 網站開發 10131

尚未有邦友留言

立即登入留言