Pengelolaan status dan sesi di ASP.NET Core

Oleh Rick Anderson, Kirk Larkin, dan Diana LaRose

HTTP adalah protokol stateless. Secara default, permintaan HTTP adalah pesan independen yang tidak mempertahankan nilai pengguna. Artikel ini menjelaskan beberapa pendekatan untuk mempertahankan data pengguna antar permintaan.

Manajemen Status

Status dapat disimpan menggunakan beberapa pendekatan. Setiap pendekatan dijelaskan nanti dalam topik ini.

Pendekatan penyimpanan Mekanisme penyimpanan
CookieS HTTP cookies. Dapat mencakup data yang disimpan menggunakan kode aplikasi sisi server.
Status sesi HTTP cookies dan kode aplikasi sisi server
TempData STATUS HTTP cookieatau sesi
String kueri String kueri HTTP
Bidang tersembunyi Bidang formulir HTTP
HttpContext.Items Kode aplikasi sisi server
Cache Kode aplikasi sisi server

Cookies

Cookies menyimpan data di seluruh permintaan. Karena cookiedikirim dengan setiap permintaan, ukurannya harus dijaga seminimal mungkin. Idealnya, hanya pengidentifikasi yang harus disimpan dalam dengan data yang cookie disimpan oleh aplikasi. Sebagian besar browser membatasi cookie ukuran hingga 4096 byte. Hanya sejumlah cookieterbatas yang tersedia untuk setiap domain.

Karena cookiedapat diubah, mereka harus divalidasi oleh aplikasi. Cookies dapat dihapus oleh pengguna dan kedaluwarsa pada klien. Namun, cookieumumnya merupakan bentuk persistensi data yang paling tahan lama pada klien.

Cookies sering digunakan untuk personalisasi, di mana konten disesuaikan untuk pengguna yang dikenal. Pengguna hanya diidentifikasi dan tidak diautentikasi dalam banyak kasus. cookie dapat menyimpan nama pengguna, nama akun, atau ID pengguna unik seperti GUID. cookie dapat digunakan untuk mengakses pengaturan pengguna yang dipersonalisasi, seperti warna latar belakang situs web pilihan mereka.

Lihat Peraturan Perlindungan Data Umum (GDPR) Uni Eropa saat menerbitkan cookiedan berurusan dengan masalah privasi. Untuk informasi selengkapnya, lihat Dukungan Peraturan Perlindungan Data Umum (GDPR) di ASP.NET Core.

Status sesi

Status sesi adalah skenario ASP.NET Core untuk penyimpanan data pengguna saat pengguna menelusuri aplikasi web. Status sesi menggunakan penyimpanan yang dikelola oleh aplikasi untuk mempertahankan data di seluruh permintaan dari klien. Data sesi didukung oleh cache dan dianggap sebagai data ephemeral. Situs harus terus berfungsi tanpa data sesi. Data aplikasi penting harus disimpan dalam database pengguna dan di-cache dalam sesi hanya sebagai pengoptimalan performa.

Sesi tidak didukung di SignalR aplikasi karena SignalR Hub dapat menjalankan independen dari konteks HTTP. Misalnya, ini dapat terjadi ketika permintaan polling panjang ditahan terbuka oleh hub di luar masa pakai konteks HTTP permintaan.

ASP.NET Core mempertahankan status sesi dengan memberikan cookie kepada klien yang berisi ID sesi. cookie ID sesi:

  • Dikirim ke aplikasi dengan setiap permintaan.
  • Digunakan oleh aplikasi untuk mengambil data sesi.

Status sesi menunjukkan perilaku berikut:

  • Sesi cookie ini khusus untuk browser. Sesi tidak dibagikan di seluruh browser.
  • Sesi cookiedihapus saat sesi browser berakhir.
  • cookie Jika diterima untuk sesi yang kedaluwarsa, sesi baru dibuat yang menggunakan sesi cookieyang sama .
  • Sesi kosong tidak dipertahankan. Sesi harus memiliki setidaknya satu nilai yang diatur untuk mempertahankan sesi di seluruh permintaan. Saat sesi tidak dipertahankan, ID sesi baru dibuat untuk setiap permintaan baru.
  • Aplikasi mempertahankan sesi untuk waktu yang terbatas setelah permintaan terakhir. Aplikasi mengatur batas waktu sesi atau menggunakan nilai default 20 menit. Status sesi sangat ideal untuk menyimpan data pengguna:
    • Itu khusus untuk sesi tertentu.
    • Jika data tidak memerlukan penyimpanan permanen di seluruh sesi.
  • Data sesi dihapus baik ketika ISession.Clear implementasi dipanggil atau ketika sesi kedaluwarsa.
  • Tidak ada mekanisme default untuk menginformasikan kode aplikasi bahwa browser klien telah ditutup atau ketika sesi cookie dihapus atau kedaluwarsa pada klien.
  • cookieStatus sesi tidak ditandai penting secara default. Status sesi tidak berfungsi kecuali pelacakan diizinkan oleh pengunjung situs. Untuk informasi selengkapnya, lihat Dukungan Peraturan Perlindungan Data Umum (GDPR) di ASP.NET Core.

Peringatan

Jangan menyimpan data sensitif dalam status sesi. Pengguna mungkin tidak menutup browser dan menghapus sesi cookie. Beberapa browser mempertahankan sesi cookieyang valid di seluruh jendela browser. Sesi mungkin tidak dibatasi untuk satu pengguna. Pengguna berikutnya mungkin terus menelusuri aplikasi dengan sesi cookieyang sama.

Penyedia cache dalam memori menyimpan data sesi di memori server tempat aplikasi berada. Dalam skenario farm server:

Mengonfigurasi status sesi

Paket Microsoft.AspNetCore.Session :

  • Disertakan secara implisit oleh kerangka kerja.
  • Menyediakan middleware untuk mengelola status sesi.

Untuk mengaktifkan middleware sesi, Program.cs harus berisi:

Kode berikut menunjukkan cara menyiapkan penyedia sesi dalam memori dengan implementasi IDistributedCachedalam memori default :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddDistributedMemoryCache();

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseSession();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

Kode sebelumnya menetapkan batas waktu singkat untuk menyederhanakan pengujian.

Urutan middleware penting. Panggil UseSession setelah UseRouting dan sebelum MapRazorPages dan MapDefaultControllerRoute . Lihat Pemesanan Middleware.

HttpContext.Session tersedia setelah status sesi dikonfigurasi.

HttpContext.Session tidak dapat diakses sebelumnya UseSession telah dipanggil.

Sesi baru dengan sesi cookie baru tidak dapat dibuat setelah aplikasi mulai menulis ke aliran respons. Pengecualian direkam di log server web dan tidak ditampilkan di browser.

Memuat status sesi secara asinkron

Penyedia sesi default di ASP.NET Core memuat rekaman sesi dari penyimpanan pendukung yang mendasar IDistributedCache secara asinkron hanya jika ISession.LoadAsync metode secara eksplisit dipanggil sebelum TryGetValuemetode , Set, atau Remove . Jika LoadAsync tidak dipanggil terlebih dahulu, catatan sesi yang mendasar dimuat secara sinkron, yang dapat dikenakan penalti performa dalam skala besar.

Agar aplikasi menerapkan pola ini, bungkus DistributedSessionStore implementasi dan DistributedSession dengan versi yang memberikan pengecualian jika LoadAsync metode tidak dipanggil sebelum TryGetValue, , Setatau Remove. Daftarkan versi yang dibungkus dalam kontainer layanan.

Opsi sesi

Untuk mengambil alih default sesi, gunakan SessionOptions.

Opsi Deskripsi
Cookie Menentukan pengaturan yang digunakan untuk membuat cookie. Name default ke SessionDefaults.CookieName (.AspNetCore.Session). Path default ke SessionDefaults.CookiePath (/). SameSite default ke SameSiteMode.Lax (1). HttpOnly default ke true. IsEssential default ke false.
IdleTimeout IdleTimeout menunjukkan berapa lama sesi dapat menganggur sebelum kontennya ditinggalkan. Setiap akses sesi mengatur ulang batas waktu. Pengaturan ini hanya berlaku untuk konten sesi, bukan cookie. Defaultnya adalah 20 menit.
IOTimeout Jumlah waktu maksimum yang diizinkan untuk memuat sesi dari penyimpanan atau menerapkannya kembali ke penyimpanan. Pengaturan ini mungkin hanya berlaku untuk operasi asinkron. Batas waktu ini dapat dinonaktifkan menggunakan InfiniteTimeSpan. Defaultnya adalah 1 menit.

Sesi menggunakan cookie untuk melacak dan mengidentifikasi permintaan dari satu browser. Secara default, ini cookie diberi nama .AspNetCore.Session, dan menggunakan jalur /. cookie Karena default tidak menentukan domain, domain tidak tersedia untuk skrip sisi klien di halaman (karena HttpOnly default ke true).

Untuk mengambil alih cookie default sesi, gunakan SessionOptions:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddDistributedMemoryCache();

builder.Services.AddSession(options =>
{
    options.Cookie.Name = ".AdventureWorks.Session";
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.IsEssential = true;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseSession();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

Aplikasi ini menggunakan IdleTimeout properti untuk menentukan berapa lama sesi dapat menganggur sebelum kontennya di cache server ditinggalkan. Properti ini tidak bergantung pada kedaluwarsa cookie . Setiap permintaan yang melewati Middleware Sesi mengatur ulang batas waktu.

Status sesi tidak terkunci. Jika dua permintaan secara bersamaan mencoba memodifikasi konten sesi, permintaan terakhir akan mengambil alih yang pertama. Session diimplementasikan sebagai sesi koheren, yang berarti bahwa semua konten disimpan bersama-sama. Ketika dua permintaan berusaha mengubah nilai sesi yang berbeda, permintaan terakhir dapat mengambil alih perubahan sesi yang dibuat oleh yang pertama.

Mengatur dan mendapatkan nilai Sesi

Status sesi diakses dari Razor kelas Pages PageModel atau kelas MVC Controller dengan HttpContext.Session. Properti ini adalah ISession implementasi.

Implementasi ini ISession menyediakan beberapa metode ekstensi untuk mengatur dan mengambil nilai bilangan bulat dan string. Metode ekstensi ada di Microsoft.AspNetCore.Http namespace.

ISession metode ekstensi:

Contoh berikut mengambil nilai sesi untuk IndexModel.SessionKeyName kunci (_Name di aplikasi sampel) di Razor halaman Halaman:

@page
@using Microsoft.AspNetCore.Http
@model IndexModel

...

Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)

Contoh berikut menunjukkan cara mengatur dan mendapatkan bilangan bulat dan string:

public class IndexModel : PageModel
{
    public const string SessionKeyName = "_Name";
    public const string SessionKeyAge = "_Age";

    private readonly ILogger<IndexModel> _logger;

    public IndexModel(ILogger<IndexModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))
        {
            HttpContext.Session.SetString(SessionKeyName, "The Doctor");
            HttpContext.Session.SetInt32(SessionKeyAge, 73);
        }
        var name = HttpContext.Session.GetString(SessionKeyName);
        var age = HttpContext.Session.GetInt32(SessionKeyAge).ToString();

        _logger.LogInformation("Session Name: {Name}", name);
        _logger.LogInformation("Session Age: {Age}", age);
    }
}

Markup berikut menampilkan nilai sesi pada Razor Halaman:

@page
@model PrivacyModel
@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<div class="text-center">
<p><b>Name:</b> @HttpContext.Session.GetString("_Name");<b>Age:

</b> @HttpContext.Session.GetInt32("_Age").ToString()</p>
</div>


Semua data sesi harus diserialisasikan untuk mengaktifkan skenario cache terdistribusi, bahkan saat menggunakan cache dalam memori. Serializer string dan bilangan bulat disediakan oleh metode ISessionekstensi . Jenis kompleks harus diserialisasikan oleh pengguna menggunakan mekanisme lain, seperti JSAKTIF.

Gunakan kode sampel berikut untuk menserialisasikan objek:

public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonSerializer.Serialize(value));
    }

    public static T? Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);
        return value == null ? default : JsonSerializer.Deserialize<T>(value);
    }
}

Contoh berikut menunjukkan cara mengatur dan mendapatkan objek yang dapat diserialisasikan dengan SessionExtensions kelas :

using Microsoft.AspNetCore.Mvc.RazorPages;
using Web.Extensions;    // SessionExtensions

namespace SessionSample.Pages
{
    public class Index6Model : PageModel
    {
        const string SessionKeyTime = "_Time";
        public string? SessionInfo_SessionTime { get; private set; }
        private readonly ILogger<Index6Model> _logger;

        public Index6Model(ILogger<Index6Model> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
            var currentTime = DateTime.Now;

            // Requires SessionExtensions from sample.
            if (HttpContext.Session.Get<DateTime>(SessionKeyTime) == default)
            {
                HttpContext.Session.Set<DateTime>(SessionKeyTime, currentTime);
            }
            _logger.LogInformation("Current Time: {Time}", currentTime);
            _logger.LogInformation("Session Time: {Time}", 
                           HttpContext.Session.Get<DateTime>(SessionKeyTime));

        }
    }
}

TempData

ASP.NET Core mengekspos RazorHalaman TempData atau Pengontrol TempData. Properti ini menyimpan data hingga dibaca dalam permintaan lain. Metode Keep(String) dan Peek(string) dapat digunakan untuk memeriksa data tanpa penghapusan di akhir permintaan. Pertahankan tandai semua item dalam kamus untuk retensi. TempData adalah:

  • Berguna untuk pengalihan saat data diperlukan untuk lebih dari satu permintaan.
  • Diimplementasikan oleh TempData penyedia menggunakan cookiestatus s atau sesi.

Sampel TempData

Pertimbangkan halaman berikut yang membuat pelanggan:

public class CreateModel : PageModel
{
    private readonly RazorPagesContactsContext _context;

    public CreateModel(RazorPagesContactsContext context)
    {
        _context = context;
    }

    public IActionResult OnGet()
    {
        return Page();
    }

    [TempData]
    public string Message { get; set; }

    [BindProperty]
    public Customer Customer { get; set; }

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Customer.Add(Customer);
        await _context.SaveChangesAsync();
        Message = $"Customer {Customer.Name} added";

        return RedirectToPage("./IndexPeek");
    }
}

Halaman berikut menampilkan TempData["Message"]:

@page
@model IndexModel

<h1>Peek Contacts</h1>

@{
    if (TempData.Peek("Message") != null)
    {
        <h3>Message: @TempData.Peek("Message")</h3>
    }
}

@*Content removed for brevity.*@

Dalam markup sebelumnya, di akhir permintaan, TempData["Message"]tidak dihapus karena Peek digunakan. Menyegarkan halaman menampilkan konten TempData["Message"].

Markup berikut mirip dengan kode sebelumnya, tetapi menggunakan Keep untuk mempertahankan data di akhir permintaan:

@page
@model IndexModel

<h1>Contacts Keep</h1>

@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
    TempData.Keep("Message");
}

@*Content removed for brevity.*@

Menavigasi antara halaman IndexPeek dan IndexKeep tidak akan menghapus TempData["Message"].

Kode berikut menampilkan TempData["Message"], tetapi di akhir permintaan, TempData["Message"] dihapus:

@page
@model IndexModel

<h1>Index no Keep or Peek</h1>

@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
}

@*Content removed for brevity.*@

Penyedia TempData

Penyedia cookieTempData berbasis digunakan secara default untuk menyimpan TempData di cookies.

Data cookie dienkripsi menggunakan IDataProtector, dikodekan dengan Base64UrlTextEncoder, lalu dipotong. Ukuran maksimum cookie kurang dari 4096 byte karena enkripsi dan penggugusan. Data cookie tidak dikompresi karena mengompresi data terenkripsi dapat menyebabkan masalah keamanan seperti CRIME serangan dan BREACH . Untuk informasi selengkapnya tentang cookiepenyedia TempData berbasis, lihat CookieTempDataProvider.

Pilih penyedia TempData

Memilih penyedia TempData melibatkan beberapa pertimbangan, seperti:

  • Apakah aplikasi sudah menggunakan status sesi? Jika demikian, menggunakan status sesi penyedia TempData tidak memiliki biaya tambahan untuk aplikasi di luar ukuran data.
  • Apakah aplikasi menggunakan TempData hanya hemat untuk jumlah data yang relatif kecil, hingga 500 byte? Jika demikian, cookie penyedia TempData menambahkan biaya kecil untuk setiap permintaan yang membawa TempData. Jika tidak, status sesi penyedia TempData dapat bermanfaat untuk menghindari round-tripping sejumlah besar data di setiap permintaan sampai TempData dikonsumsi.
  • Apakah aplikasi berjalan di farm server di beberapa server? Jika demikian, tidak ada konfigurasi tambahan yang diperlukan untuk menggunakan cookie penyedia TempData di luar Perlindungan Data. Untuk informasi selengkapnya, lihat ASP.NET Gambaran Umum Perlindungan Data Inti dan Penyedia penyimpanan utama.

Sebagian besar klien web seperti browser web memberlakukan batasan pada ukuran maksimum masing-masing cookie dan jumlah cookietotal. Saat menggunakan cookie penyedia TempData, verifikasi aplikasi tidak akan melebihi batas ini. Pertimbangkan ukuran total data. Mempertanggungjawabkan cookie peningkatan ukuran karena enkripsi dan penggugusan.

Mengonfigurasi penyedia TempData

Penyedia cookieTempData berbasis diaktifkan secara default.

Untuk mengaktifkan penyedia TempData berbasis sesi, gunakan AddSessionStateTempDataProvider metode ekstensi. Hanya diperlukan satu panggilan ke AddSessionStateTempDataProvider :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages()
                    .AddSessionStateTempDataProvider();
builder.Services.AddControllersWithViews()
                    .AddSessionStateTempDataProvider();

builder.Services.AddSession();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseSession();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

String kueri

Sejumlah data terbatas dapat diteruskan dari satu permintaan ke permintaan lain dengan menambahkannya ke string kueri permintaan baru. Ini berguna untuk menangkap status dengan cara yang persisten yang memungkinkan tautan dengan status tersemat dibagikan melalui email atau jejaring sosial. Karena string kueri URL bersifat publik, jangan pernah menggunakan string kueri untuk data sensitif.

Selain berbagi yang tidak diinginkan, termasuk data dalam string kueri dapat mengekspos aplikasi ke serangan Pemalsuan Permintaan Lintas Situs (CSRF ). Setiap status sesi yang dipertahankan harus melindungi dari serangan CSRF. Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core.

Bidang tersembunyi

Data dapat disimpan dalam bidang formulir tersembunyi dan diposting kembali pada permintaan berikutnya. Ini umum dalam formulir multi-halaman. Karena klien berpotensi mengubah data, aplikasi harus selalu memvalidasi ulang data yang disimpan di bidang tersembunyi.

HttpContext.Items

Koleksi HttpContext.Items digunakan untuk menyimpan data saat memproses satu permintaan. Konten koleksi dibuang setelah permintaan diproses. Koleksi Items ini sering digunakan untuk memungkinkan komponen atau middleware berkomunikasi ketika mereka beroperasi pada titik waktu yang berbeda selama permintaan dan tidak memiliki cara langsung untuk melewati parameter.

Dalam contoh berikut, middleware menambahkan isVerified ke Items koleksi:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

ILogger logger = app.Logger;

app.Use(async (context, next) =>
{
    // context.Items["isVerified"] is null
    logger.LogInformation($"Before setting: Verified: {context.Items["isVerified"]}");
    context.Items["isVerified"] = true;
    await next.Invoke();
});

app.Use(async (context, next) =>
{
    // context.Items["isVerified"] is true
    logger.LogInformation($"Next: Verified: {context.Items["isVerified"]}");
    await next.Invoke();
});

app.MapGet("/", async context =>
{
    await context.Response.WriteAsync($"Verified: {context.Items["isVerified"]}");
});

app.Run();

Untuk middleware yang hanya digunakan dalam satu aplikasi, tidak mungkin menggunakan kunci tetap akan menyebabkan tabrakan string kunci. Namun, untuk menghindari kemungkinan tabrakan kunci sama sekali, object dapat digunakan sebagai kunci item. Pendekatan ini sangat berguna untuk middleware yang dibagikan antara aplikasi dan juga memiliki keuntungan menghilangkan penggunaan string kunci dalam kode. Contoh berikut menunjukkan cara menggunakan kunci yang object ditentukan dalam kelas middleware:

public class HttpContextItemsMiddleware
{
    private readonly RequestDelegate _next;
    public static readonly object HttpContextItemsMiddlewareKey = new();

    public HttpContextItemsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        httpContext.Items[HttpContextItemsMiddlewareKey] = "K-9";

        await _next(httpContext);
    }
}

public static class HttpContextItemsMiddlewareExtensions
{
    public static IApplicationBuilder 
        UseHttpContextItemsMiddleware(this IApplicationBuilder app)
    {
        return app.UseMiddleware<HttpContextItemsMiddleware>();
    }
}

Kode lain dapat mengakses nilai yang disimpan dalam HttpContext.Items menggunakan kunci yang diekspos oleh kelas middleware:

public class Index2Model : PageModel
{
    private readonly ILogger<Index2Model> _logger;

    public Index2Model(ILogger<Index2Model> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        HttpContext.Items
            .TryGetValue(HttpContextItemsMiddleware.HttpContextItemsMiddlewareKey,
                out var middlewareSetValue);

        _logger.LogInformation("Middleware value {MV}",
            middlewareSetValue?.ToString() ?? "Middleware value not set!");
    }
}

Cache

Penembolokan adalah cara yang efisien untuk menyimpan dan mengambil data. Aplikasi ini dapat mengontrol masa pakai item yang di-cache. Untuk informasi selengkapnya, lihat Penembolokan respons di ASP.NET Core.

Data yang di-cache tidak terkait dengan permintaan, pengguna, atau sesi tertentu. Jangan cache data khusus pengguna yang dapat diambil oleh permintaan pengguna lain.

Untuk menyimpan data luas aplikasi, lihat Cache dalam memori di ASP.NET Core.

Kesalahan umum

  • "Tidak dapat mengatasi layanan untuk jenis 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' saat mencoba mengaktifkan 'Microsoft.AspNetCore.Session.DistributedSessionStore'."

    Hal ini biasanya disebabkan oleh gagal mengonfigurasi setidaknya satu IDistributedCache implementasi. Untuk informasi selengkapnya, lihat Penembolokan terdistribusi di ASP.NET Core dan Cache dalam memori di ASP.NET Core.

Jika middleware sesi gagal mempertahankan sesi:

  • Middleware mencatat pengecualian dan permintaan berlanjut secara normal.
  • Hal ini menyebabkan perilaku yang tidak dapat diprediksi.

Middleware sesi dapat gagal mempertahankan sesi jika penyimpanan dukungan tidak tersedia. Misalnya, pengguna menyimpan kedai belanja dalam sesi. Pengguna menambahkan item ke kerajinan tetapi penerapan gagal. Aplikasi tidak tahu tentang kegagalan sehingga melaporkan kepada pengguna bahwa item ditambahkan ke kelima mereka, yang tidak benar.

Pendekatan yang disarankan untuk memeriksa kesalahan adalah memanggil await feature.Session.CommitAsync ketika aplikasi selesai menulis ke sesi. CommitAsync melempar pengecualian jika penyimpanan cadangan tidak tersedia. Jika CommitAsync gagal, aplikasi dapat memproses pengecualian. LoadAsync dilemparkan dalam kondisi yang sama ketika penyimpanan data tidak tersedia.

SignalR dan keadaan sesi

SignalR aplikasi tidak boleh menggunakan status sesi untuk menyimpan informasi. SignalR aplikasi dapat menyimpan per status koneksi di Context.Items hub.

Sumber Daya Tambahan:

Melihat atau mengunduh kode sampel (cara mengunduh)

Host ASP.NET Core di farm web

Oleh Rick Anderson, Kirk Larkin, dan Diana LaRose

HTTP adalah protokol stateless. Secara default, permintaan HTTP adalah pesan independen yang tidak mempertahankan nilai pengguna. Artikel ini menjelaskan beberapa pendekatan untuk mempertahankan data pengguna antar permintaan.

Melihat atau mengunduh kode sampel (cara mengunduh)

Manajemen Status

Status dapat disimpan menggunakan beberapa pendekatan. Setiap pendekatan dijelaskan nanti dalam topik ini.

Pendekatan penyimpanan Mekanisme penyimpanan
CookieS HTTP cookies. Dapat mencakup data yang disimpan menggunakan kode aplikasi sisi server.
Status sesi HTTP cookies dan kode aplikasi sisi server
TempData STATUS HTTP cookieatau sesi
String kueri String kueri HTTP
Bidang tersembunyi Bidang formulir HTTP
HttpContext.Items Kode aplikasi sisi server
Cache Kode aplikasi sisi server

Cookies

Cookies menyimpan data di seluruh permintaan. Karena cookiedikirim dengan setiap permintaan, ukurannya harus dijaga seminimal mungkin. Idealnya, hanya pengidentifikasi yang harus disimpan dalam dengan data yang cookie disimpan oleh aplikasi. Sebagian besar browser membatasi cookie ukuran hingga 4096 byte. Hanya sejumlah cookieterbatas yang tersedia untuk setiap domain.

Karena cookiedapat diubah, mereka harus divalidasi oleh aplikasi. Cookies dapat dihapus oleh pengguna dan kedaluwarsa pada klien. Namun, cookieumumnya merupakan bentuk persistensi data yang paling tahan lama pada klien.

Cookies sering digunakan untuk personalisasi, di mana konten disesuaikan untuk pengguna yang dikenal. Pengguna hanya diidentifikasi dan tidak diautentikasi dalam banyak kasus. cookie dapat menyimpan nama pengguna, nama akun, atau ID pengguna unik seperti GUID. cookie dapat digunakan untuk mengakses pengaturan pengguna yang dipersonalisasi, seperti warna latar belakang situs web pilihan mereka.

Lihat Peraturan Perlindungan Data Umum (GDPR) Uni Eropa saat menerbitkan cookiedan berurusan dengan masalah privasi. Untuk informasi selengkapnya, lihat Dukungan Peraturan Perlindungan Data Umum (GDPR) di ASP.NET Core.

Status sesi

Status sesi adalah skenario ASP.NET Core untuk penyimpanan data pengguna saat pengguna menelusuri aplikasi web. Status sesi menggunakan penyimpanan yang dikelola oleh aplikasi untuk mempertahankan data di seluruh permintaan dari klien. Data sesi didukung oleh cache dan dianggap sebagai data ephemeral. Situs harus terus berfungsi tanpa data sesi. Data aplikasi penting harus disimpan dalam database pengguna dan di-cache dalam sesi hanya sebagai pengoptimalan performa.

Sesi tidak didukung di SignalR aplikasi karena SignalR Hub dapat menjalankan independen dari konteks HTTP. Misalnya, ini dapat terjadi ketika permintaan polling panjang ditahan terbuka oleh hub di luar masa pakai konteks HTTP permintaan.

ASP.NET Core mempertahankan status sesi dengan memberikan cookie kepada klien yang berisi ID sesi. cookie ID sesi:

  • Dikirim ke aplikasi dengan setiap permintaan.
  • Digunakan oleh aplikasi untuk mengambil data sesi.

Status sesi menunjukkan perilaku berikut:

  • Sesi cookie ini khusus untuk browser. Sesi tidak dibagikan di seluruh browser.
  • Sesi cookiedihapus saat sesi browser berakhir.
  • cookie Jika diterima untuk sesi yang kedaluwarsa, sesi baru dibuat yang menggunakan sesi cookieyang sama .
  • Sesi kosong tidak dipertahankan. Sesi harus memiliki setidaknya satu nilai yang diatur untuk mempertahankan sesi di seluruh permintaan. Saat sesi tidak dipertahankan, ID sesi baru dibuat untuk setiap permintaan baru.
  • Aplikasi mempertahankan sesi untuk waktu yang terbatas setelah permintaan terakhir. Aplikasi mengatur batas waktu sesi atau menggunakan nilai default 20 menit. Status sesi sangat ideal untuk menyimpan data pengguna:
    • Itu khusus untuk sesi tertentu.
    • Jika data tidak memerlukan penyimpanan permanen di seluruh sesi.
  • Data sesi dihapus baik ketika ISession.Clear implementasi dipanggil atau ketika sesi kedaluwarsa.
  • Tidak ada mekanisme default untuk menginformasikan kode aplikasi bahwa browser klien telah ditutup atau ketika sesi cookie dihapus atau kedaluwarsa pada klien.
  • cookieStatus sesi tidak ditandai penting secara default. Status sesi tidak berfungsi kecuali pelacakan diizinkan oleh pengunjung situs. Untuk informasi selengkapnya, lihat Dukungan Peraturan Perlindungan Data Umum (GDPR) di ASP.NET Core.

Peringatan

Jangan menyimpan data sensitif dalam status sesi. Pengguna mungkin tidak menutup browser dan menghapus sesi cookie. Beberapa browser mempertahankan sesi cookieyang valid di seluruh jendela browser. Sesi mungkin tidak dibatasi untuk satu pengguna. Pengguna berikutnya mungkin terus menelusuri aplikasi dengan sesi cookieyang sama.

Penyedia cache dalam memori menyimpan data sesi di memori server tempat aplikasi berada. Dalam skenario farm server:

Mengonfigurasi status sesi

Paket Microsoft.AspNetCore.Session :

  • Disertakan secara implisit oleh kerangka kerja.
  • Menyediakan middleware untuk mengelola status sesi.

Untuk mengaktifkan middleware sesi, Startup harus berisi:

Kode berikut menunjukkan cara menyiapkan penyedia sesi dalam memori dengan implementasi IDistributedCachedalam memori default :

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        });

        services.AddControllersWithViews();
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseSession();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
            endpoints.MapRazorPages();
        });
    }
}

Kode sebelumnya menetapkan batas waktu singkat untuk menyederhanakan pengujian.

Urutan middleware penting. Panggil UseSession setelah UseRouting dan sebelum UseEndpoints. Lihat Pemesanan Middleware.

HttpContext.Session tersedia setelah status sesi dikonfigurasi.

HttpContext.Session tidak dapat diakses sebelumnya UseSession telah dipanggil.

Sesi baru dengan sesi cookie baru tidak dapat dibuat setelah aplikasi mulai menulis ke aliran respons. Pengecualian direkam di log server web dan tidak ditampilkan di browser.

Memuat status sesi secara asinkron

Penyedia sesi default di ASP.NET Core memuat rekaman sesi dari penyimpanan pendukung yang mendasar IDistributedCache secara asinkron hanya jika ISession.LoadAsync metode secara eksplisit dipanggil sebelum TryGetValuemetode , Set, atau Remove . Jika LoadAsync tidak dipanggil terlebih dahulu, catatan sesi yang mendasar dimuat secara sinkron, yang dapat dikenakan penalti performa dalam skala besar.

Agar aplikasi menerapkan pola ini, bungkus DistributedSessionStore implementasi dan DistributedSession dengan versi yang memberikan pengecualian jika LoadAsync metode tidak dipanggil sebelum TryGetValue, , Setatau Remove. Daftarkan versi yang dibungkus dalam kontainer layanan.

Opsi sesi

Untuk mengambil alih default sesi, gunakan SessionOptions.

Opsi Deskripsi
Cookie Menentukan pengaturan yang digunakan untuk membuat cookie. Name default ke SessionDefaults.CookieName (.AspNetCore.Session). Path default ke SessionDefaults.CookiePath (/). SameSite default ke SameSiteMode.Lax (1). HttpOnly default ke true. IsEssential default ke false.
IdleTimeout IdleTimeout menunjukkan berapa lama sesi dapat menganggur sebelum kontennya ditinggalkan. Setiap akses sesi mengatur ulang batas waktu. Pengaturan ini hanya berlaku untuk konten sesi, bukan cookie. Defaultnya adalah 20 menit.
IOTimeout Jumlah waktu maksimum yang diizinkan untuk memuat sesi dari penyimpanan atau menerapkannya kembali ke penyimpanan. Pengaturan ini mungkin hanya berlaku untuk operasi asinkron. Batas waktu ini dapat dinonaktifkan menggunakan InfiniteTimeSpan. Defaultnya adalah 1 menit.

Sesi menggunakan cookie untuk melacak dan mengidentifikasi permintaan dari satu browser. Secara default, ini cookie diberi nama .AspNetCore.Session, dan menggunakan jalur /. cookie Karena default tidak menentukan domain, domain tidak tersedia untuk skrip sisi klien di halaman (karena HttpOnly default ke true).

Untuk mengambil alih cookie default sesi, gunakan SessionOptions:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDistributedMemoryCache();

    services.AddSession(options =>
    {
        options.Cookie.Name = ".AdventureWorks.Session";
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.Cookie.IsEssential = true;
    });

    services.AddControllersWithViews();
    services.AddRazorPages();
}

Aplikasi ini menggunakan IdleTimeout properti untuk menentukan berapa lama sesi dapat menganggur sebelum kontennya di cache server ditinggalkan. Properti ini tidak bergantung pada kedaluwarsa cookie . Setiap permintaan yang melewati Middleware Sesi mengatur ulang batas waktu.

Status sesi tidak terkunci. Jika dua permintaan secara bersamaan mencoba memodifikasi konten sesi, permintaan terakhir akan mengambil alih yang pertama. Session diimplementasikan sebagai sesi koheren, yang berarti bahwa semua konten disimpan bersama-sama. Ketika dua permintaan berusaha mengubah nilai sesi yang berbeda, permintaan terakhir dapat mengambil alih perubahan sesi yang dibuat oleh yang pertama.

Mengatur dan mendapatkan nilai Sesi

Status sesi diakses dari Razor kelas Pages PageModel atau kelas MVC Controller dengan HttpContext.Session. Properti ini adalah ISession implementasi.

Implementasi ini ISession menyediakan beberapa metode ekstensi untuk mengatur dan mengambil nilai bilangan bulat dan string. Metode ekstensi ada di Microsoft.AspNetCore.Http namespace.

ISession metode ekstensi:

Contoh berikut mengambil nilai sesi untuk IndexModel.SessionKeyName kunci (_Name di aplikasi sampel) di Razor halaman Halaman:

@page
@using Microsoft.AspNetCore.Http
@model IndexModel

...

Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)

Contoh berikut menunjukkan cara mengatur dan mendapatkan bilangan bulat dan string:

public class IndexModel : PageModel
{
    public const string SessionKeyName = "_Name";
    public const string SessionKeyAge = "_Age";
    const string SessionKeyTime = "_Time";

    public string SessionInfo_Name { get; private set; }
    public string SessionInfo_Age { get; private set; }
    public string SessionInfo_CurrentTime { get; private set; }
    public string SessionInfo_SessionTime { get; private set; }
    public string SessionInfo_MiddlewareValue { get; private set; }

    public void OnGet()
    {
        // Requires: using Microsoft.AspNetCore.Http;
        if (string.IsNullOrEmpty(HttpContext.Session.GetString(SessionKeyName)))
        {
            HttpContext.Session.SetString(SessionKeyName, "The Doctor");
            HttpContext.Session.SetInt32(SessionKeyAge, 773);
        }

        var name = HttpContext.Session.GetString(SessionKeyName);
        var age = HttpContext.Session.GetInt32(SessionKeyAge);

Semua data sesi harus diserialisasikan untuk mengaktifkan skenario cache terdistribusi, bahkan saat menggunakan cache dalam memori. Serializer string dan bilangan bulat disediakan oleh metode ISessionekstensi . Jenis kompleks harus diserialisasikan oleh pengguna menggunakan mekanisme lain, seperti JSAKTIF.

Gunakan kode sampel berikut untuk menserialisasikan objek:

public static class SessionExtensions
{
    public static void Set<T>(this ISession session, string key, T value)
    {
        session.SetString(key, JsonSerializer.Serialize(value));
    }

    public static T Get<T>(this ISession session, string key)
    {
        var value = session.GetString(key);
        return value == null ? default : JsonSerializer.Deserialize<T>(value);
    }
}

Contoh berikut menunjukkan cara mengatur dan mendapatkan objek yang dapat diserialisasikan dengan SessionExtensions kelas :

// Requires SessionExtensions from sample download.
if (HttpContext.Session.Get<DateTime>(SessionKeyTime) == default)
{
    HttpContext.Session.Set<DateTime>(SessionKeyTime, currentTime);
}

TempData

ASP.NET Core mengekspos RazorHalaman TempData atau Pengontrol TempData. Properti ini menyimpan data hingga dibaca dalam permintaan lain. Metode Keep(String) dan Peek(string) dapat digunakan untuk memeriksa data tanpa penghapusan di akhir permintaan. Pertahankan tandai semua item dalam kamus untuk retensi. TempData adalah:

  • Berguna untuk pengalihan saat data diperlukan untuk lebih dari satu permintaan.
  • Diimplementasikan oleh TempData penyedia menggunakan cookiestatus s atau sesi.

Sampel TempData

Pertimbangkan halaman berikut yang membuat pelanggan:

public class CreateModel : PageModel
{
    private readonly RazorPagesContactsContext _context;

    public CreateModel(RazorPagesContactsContext context)
    {
        _context = context;
    }

    public IActionResult OnGet()
    {
        return Page();
    }

    [TempData]
    public string Message { get; set; }

    [BindProperty]
    public Customer Customer { get; set; }

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Customer.Add(Customer);
        await _context.SaveChangesAsync();
        Message = $"Customer {Customer.Name} added";

        return RedirectToPage("./IndexPeek");
    }
}

Halaman berikut menampilkan TempData["Message"]:

@page
@model IndexModel

<h1>Peek Contacts</h1>

@{
    if (TempData.Peek("Message") != null)
    {
        <h3>Message: @TempData.Peek("Message")</h3>
    }
}

@*Content removed for brevity.*@

Dalam markup sebelumnya, di akhir permintaan, TempData["Message"]tidak dihapus karena Peek digunakan. Menyegarkan halaman menampilkan konten TempData["Message"].

Markup berikut mirip dengan kode sebelumnya, tetapi menggunakan Keep untuk mempertahankan data di akhir permintaan:

@page
@model IndexModel

<h1>Contacts Keep</h1>

@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
    TempData.Keep("Message");
}

@*Content removed for brevity.*@

Menavigasi antara halaman IndexPeek dan IndexKeep tidak akan menghapus TempData["Message"].

Kode berikut menampilkan TempData["Message"], tetapi di akhir permintaan, TempData["Message"] dihapus:

@page
@model IndexModel

<h1>Index no Keep or Peek</h1>

@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
}

@*Content removed for brevity.*@

Penyedia TempData

Penyedia cookieTempData berbasis digunakan secara default untuk menyimpan TempData di cookies.

Data cookie dienkripsi menggunakan IDataProtector, dikodekan dengan Base64UrlTextEncoder, lalu dipotong. Ukuran maksimum cookie kurang dari 4096 byte karena enkripsi dan penggugusan. Data cookie tidak dikompresi karena mengompresi data terenkripsi dapat menyebabkan masalah keamanan seperti CRIME serangan dan BREACH . Untuk informasi selengkapnya tentang cookiepenyedia TempData berbasis, lihat CookieTempDataProvider.

Pilih penyedia TempData

Memilih penyedia TempData melibatkan beberapa pertimbangan, seperti:

  • Apakah aplikasi sudah menggunakan status sesi? Jika demikian, menggunakan status sesi penyedia TempData tidak memiliki biaya tambahan untuk aplikasi di luar ukuran data.
  • Apakah aplikasi menggunakan TempData hanya hemat untuk jumlah data yang relatif kecil, hingga 500 byte? Jika demikian, cookie penyedia TempData menambahkan biaya kecil untuk setiap permintaan yang membawa TempData. Jika tidak, status sesi penyedia TempData dapat bermanfaat untuk menghindari round-tripping sejumlah besar data di setiap permintaan sampai TempData dikonsumsi.
  • Apakah aplikasi berjalan di farm server di beberapa server? Jika demikian, tidak ada konfigurasi tambahan yang diperlukan untuk menggunakan cookie penyedia TempData di luar Perlindungan Data (lihat ASP.NET Gambaran Umum Perlindungan Data Inti dan Penyedia penyimpanan utama).

Sebagian besar klien web seperti browser web memberlakukan batasan pada ukuran maksimum masing-masing cookie dan jumlah cookietotal. Saat menggunakan cookie penyedia TempData, verifikasi aplikasi tidak akan melebihi batas ini. Pertimbangkan ukuran total data. Mempertanggungjawabkan cookie peningkatan ukuran karena enkripsi dan penggugusan.

Mengonfigurasi penyedia TempData

Penyedia cookieTempData berbasis diaktifkan secara default.

Untuk mengaktifkan penyedia TempData berbasis sesi, gunakan AddSessionStateTempDataProvider metode ekstensi. Hanya diperlukan satu panggilan ke AddSessionStateTempDataProvider :

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews()
        .AddSessionStateTempDataProvider();
    services.AddRazorPages()
        .AddSessionStateTempDataProvider();

    services.AddSession();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseSession();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
        endpoints.MapRazorPages();
    });
}

String kueri

Sejumlah data terbatas dapat diteruskan dari satu permintaan ke permintaan lain dengan menambahkannya ke string kueri permintaan baru. Ini berguna untuk menangkap status dengan cara yang persisten yang memungkinkan tautan dengan status tersemat dibagikan melalui email atau jejaring sosial. Karena string kueri URL bersifat publik, jangan pernah menggunakan string kueri untuk data sensitif.

Selain berbagi yang tidak diinginkan, termasuk data dalam string kueri dapat mengekspos aplikasi ke serangan Pemalsuan Permintaan Lintas Situs (CSRF ). Setiap status sesi yang dipertahankan harus melindungi dari serangan CSRF. Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core.

Bidang tersembunyi

Data dapat disimpan dalam bidang formulir tersembunyi dan diposting kembali pada permintaan berikutnya. Ini umum dalam formulir multi-halaman. Karena klien berpotensi mengubah data, aplikasi harus selalu memvalidasi ulang data yang disimpan di bidang tersembunyi.

HttpContext.Items

Koleksi HttpContext.Items digunakan untuk menyimpan data saat memproses satu permintaan. Konten koleksi dibuang setelah permintaan diproses. Koleksi Items ini sering digunakan untuk memungkinkan komponen atau middleware berkomunikasi ketika mereka beroperasi pada titik waktu yang berbeda selama permintaan dan tidak memiliki cara langsung untuk melewati parameter.

Dalam contoh berikut, middleware menambahkan isVerified ke Items koleksi:

public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
{
    app.UseRouting();

    app.Use(async (context, next) =>
    {
        logger.LogInformation($"Before setting: Verified: {context.Items["isVerified"]}");
        context.Items["isVerified"] = true;
        await next.Invoke();
    });

    app.Use(async (context, next) =>
    {
        logger.LogInformation($"Next: Verified: {context.Items["isVerified"]}");
        await next.Invoke();
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync($"Verified: {context.Items["isVerified"]}");
        });
    });
}

Untuk middleware yang hanya digunakan dalam satu aplikasi, kunci tetap string dapat diterima. Middleware yang dibagikan antar aplikasi harus menggunakan kunci objek unik untuk menghindari tabrakan kunci. Contoh berikut menunjukkan cara menggunakan kunci objek unik yang ditentukan dalam kelas middleware:

public class HttpContextItemsMiddleware
{
    private readonly RequestDelegate _next;
    public static readonly object HttpContextItemsMiddlewareKey = new Object();

    public HttpContextItemsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        httpContext.Items[HttpContextItemsMiddlewareKey] = "K-9";

        await _next(httpContext);
    }
}

public static class HttpContextItemsMiddlewareExtensions
{
    public static IApplicationBuilder 
        UseHttpContextItemsMiddleware(this IApplicationBuilder app)
    {
        return app.UseMiddleware<HttpContextItemsMiddleware>();
    }
}

Kode lain dapat mengakses nilai yang disimpan dalam HttpContext.Items menggunakan kunci yang diekspos oleh kelas middleware:

HttpContext.Items
    .TryGetValue(HttpContextItemsMiddleware.HttpContextItemsMiddlewareKey, 
        out var middlewareSetValue);
SessionInfo_MiddlewareValue = 
    middlewareSetValue?.ToString() ?? "Middleware value not set!";

Pendekatan ini juga memiliki keuntungan menghilangkan penggunaan string kunci dalam kode.

Cache

Penembolokan adalah cara yang efisien untuk menyimpan dan mengambil data. Aplikasi ini dapat mengontrol masa pakai item yang di-cache. Untuk informasi selengkapnya, lihat Penembolokan respons di ASP.NET Core.

Data yang di-cache tidak terkait dengan permintaan, pengguna, atau sesi tertentu. Jangan cache data khusus pengguna yang dapat diambil oleh permintaan pengguna lain.

Untuk menyimpan data luas aplikasi, lihat Cache dalam memori di ASP.NET Core.

Kesalahan umum

  • "Tidak dapat mengatasi layanan untuk jenis 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' saat mencoba mengaktifkan 'Microsoft.AspNetCore.Session.DistributedSessionStore'."

    Hal ini biasanya disebabkan oleh gagal mengonfigurasi setidaknya satu IDistributedCache implementasi. Untuk informasi selengkapnya, lihat Penembolokan terdistribusi di ASP.NET Core dan Cache dalam memori di ASP.NET Core.

Jika middleware sesi gagal mempertahankan sesi:

  • Middleware mencatat pengecualian dan permintaan berlanjut secara normal.
  • Hal ini menyebabkan perilaku yang tidak dapat diprediksi.

Middleware sesi dapat gagal mempertahankan sesi jika penyimpanan dukungan tidak tersedia. Misalnya, pengguna menyimpan kedai belanja dalam sesi. Pengguna menambahkan item ke kerajinan tetapi penerapan gagal. Aplikasi tidak tahu tentang kegagalan sehingga melaporkan kepada pengguna bahwa item ditambahkan ke kelima mereka, yang tidak benar.

Pendekatan yang disarankan untuk memeriksa kesalahan adalah memanggil await feature.Session.CommitAsync ketika aplikasi selesai menulis ke sesi. CommitAsync melempar pengecualian jika penyimpanan cadangan tidak tersedia. Jika CommitAsync gagal, aplikasi dapat memproses pengecualian. LoadAsync dilemparkan dalam kondisi yang sama ketika penyimpanan data tidak tersedia.

SignalR dan keadaan sesi

SignalR aplikasi tidak boleh menggunakan status sesi untuk menyimpan informasi. SignalR aplikasi dapat menyimpan per status koneksi di Context.Items hub.

Sumber Daya Tambahan:

Host ASP.NET Core di farm web