C# cơ bản .NET Core

Session trong ASP.NET

Session là cơ chế để lưu lại dữ liệu của phiên làm việc cho của ứng dụng - ứng với từng khách truy cập. Để trao đổi dữ liệu từ trang này qua trang khác. Ví dụ nếu người dùng đã đăng nhập, thì thông tin đăng nhập được lưu lại và chuyển cho các trang khác nhau trong phiên làm việc để khỏi mỗi lần gửi request lại phải đăng nhập, hay người dùng chọn đựa mặt hàng vào giỏ hàng thì phải nhớ khi chuyển đến trang thanh toán ...

Để thực hành hãy copy mã nguồn ở ví dụ phần trước đây Sử dụng IServiceCollection trong ASP.NET , hãy copy mã nguồn ví dụ bài trước ASP_NET_CORE/04.ServiceCollection đổi tên thư mục thành 05.Session để sử dụng lại

Dữ liệu Session lưu trữ trên Server có thể là ở bộ nhớ Cache, có thể là ở CSDL SQLServer hoặc những nguồn lưu cache khác nhau. Ở đây ta sẽ sử dụng bộ nhớ làm Storage lưu dữ liệu Session. Để ứng dụng sử dụng Session thêm vào dự án Package như sau:

dotnet add package Microsoft.AspNetCore.Session
dotnet add package Microsoft.Extensions.Caching.Memory

Kích hoạt Session trong ASP.NET

Mở lớp Startup thêm vào phương thức ConfigureServicesConfigure code sau:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        /..
        services.AddDistributedMemoryCache();           // Đăng ký dịch vụ lưu cache trong bộ nhớ (Session sẽ sử dụng nó)
        services.AddSession(cfg => {                    // Đăng ký dịch vụ Session
            cfg.Cookie.Name = "xuanthulab";             // Đặt tên Session - tên này sử dụng ở Browser (Cookie)
            cfg.IdleTimeout = new TimeSpan(0,60, 0);    // Thời gian tồn tại của Session
         });
        /..
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        /..
        app.UseSession();                               // Đăng ký Middleware Session vào Pipeline
        /..

    }
}
    

Bằng cách đăng ký như vậy, ứng dụng sẽ có một đối tượng kiểu ISession để làm việc với Session. Đối tượng này lấy được từ thuộc tính của HttpContext

// Lấy ISession - context là đối tượng kiểu HttpContext do ứng dụng cung cấp
var session = context.Session;

ISession và DistributedSession

Giao diện ISession triển khai trong ứng dụng ASP.NET mà ta lấy được ở trên là lớp DistributedSession, sau đây là một số phương thức, thuộc tính của nó

Member Ý nghĩa
ID Thuộc tính lấy ID của Session, ID này có gửi về lưu ở Cookie
Clear() Xóa bỏ các giá trị lưu trong Session
Set(String key, Byte[]) Lưu mảng byte vào Session với key chỉ ra
TryGetValue(String key, Byte[]) Lấy dữ liệu lưu trong key (trả về false là có thành công)
SetString(String key, String s) Lưu chuỗi vào key
GetString(String key) Lấy chuỗi lưu trong key
SetInt32(String key, Int32 val) Lưu số kiểu int32 vào key
GetInt32(String key) Lấy số int32 trong key

Lưu và đọc dữ liệu Session

Giả sử ta muốn lưu thông tin một khách truy cập vào trang /Product (xem ví dụ trước), gồm dữ liệu là số lần truy cập, và thời điểm cuối truy cập.

Đối tượng này ở dạng lớp vô danh với cấu trúc

{
    count = 0,                  // số lần truy cập
    lasttime  = DateTime.Now    // thời điểm cuối truy cập
}

Đối tượng này được lưu vào Session dưới dạng chuỗi Json, nên cần đảm bảo có Package Newtonsoft.Json (từng giới thiệu ở Trả về nội dung Json), cặt đặt package như sau:

dotnet add package Newtonsoft.Json

Vì khi sử dụng thì nạp namespace

using Newtonsoft.Json;

Áp dụng: Mở file ProductController.cs thêm phương thức sau:

/..
public void CountAccess(HttpContext context) {
    // Lấy ISession
    var session       = context.Session;
    string key_access = "info_access";

    // Lưu vào  Session thông tin truy cập
    // Định nghĩa cấu trúc dữ liệu lưu trong Session
    var accessInfoType = new  {
        count     = 0,
        lasttime  = DateTime.Now
    };

    // Đọc chuỗi lưu trong Sessin với key = info_access
    string json = session.GetString(key_access);
    dynamic lastAccessInfo;
    if (json != null) { 
        // Convert chuỗi Json - thành đối tượng có cấu trúc như accessInfoType
        lastAccessInfo = JsonConvert.DeserializeObject(json, accessInfoType.GetType());
    }
    else { 
        // json chưa từng lưu trong Session, accessInfo lấy bằng giá trị khởi  tạo
        lastAccessInfo  = accessInfoType;
    }

    // Cập nhật thông tin
    var accessInfoSave = new {
        count     = lastAccessInfo.count + 1,
        lasttime  = DateTime.Now
    }; 

    // Convert accessInfo thành chuỗi Json và lưu lại vào Session
    string jsonSave = JsonConvert.SerializeObject(accessInfoSave);
    session.SetString(key_access, jsonSave);
    Console.WriteLine(jsonSave);
}
/..

Sau đó bạn nó vào phương thức List

/..
public async Task List(HttpContext context) {
    /..
    CountAccess(context);
    /..
}
/..

Giờ mỗi lần truy cập trang /Product thì nó sẽ đọc và cập nhật Session với key là info_access

Thông tin Session trên có thể đọc bất kỳ ở trang nào. Ví dụ, thêm vào phương thức


public class ProductController
{
    //..
    public static string CountAccessInfo(HttpContext context) {
        var session       = context.Session;          // Lấy ISession
        string key_access = "info_access";

        // Lưu vào  Session thông tin truy cập
        // Định nghĩa cấu trúc dữ liệu lưu trong Session
        var accessInfoType = new  {
            count     = 0,
            lasttime  = DateTime.Now
        };

        // Đọc chuỗi lưu trong Sessin với key = info_access
        string json = session.GetString(key_access);
        dynamic lastAccessInfo;
        if (json != null) {
            // Convert chuỗi Json - thành đối tượng
            lastAccessInfo = JsonConvert.DeserializeObject(json, accessInfoType.GetType());
        }
        else {
            // json chưa từng lưu trong Session, accessInfo lấy bằng giá trị khởi  tạo
            lastAccessInfo  = accessInfoType;
        }
        if (lastAccessInfo.count == 0) {
            return "Chưa truy cập /Product lần  nào".HtmlTag("p");
        }

        string thongtin = $"Số lần truy cập /Product: {lastAccessInfo.count}  - lần cuối: {lastAccessInfo.lasttime.ToLongTimeString()}";
        return thongtin;
    }
    //..

}

Ví dụ, áp dụng ở trang /RequestInfo (Copy thêm mã nguồn này vào RequestProcess.cs )

/..
app.Map("/RequestInfo", app01 => {
    app01.Run(async (context) => {
        string menu         = HtmlHelper.MenuTop(HtmlHelper.DefaultMenuTopItems(), context.Request);
        string requestinfo  = RequestProcess.RequestInfo(context.Request).HtmlTag("div", "container");

        string accessinfo  = ProductController.CountAccessInfo(context).HtmlTag("div", "container");

        string html         = HtmlHelper.HtmlDocument("Thông tin Request", (menu + accessinfo + requestinfo));
        await context.Response.WriteAsync(html);
    });
});
/..

Tham khảo mã nguồn ASP_NET_CORE/05.Session hoặc tải về


Đăng ký nhận bài viết mới