Megosztás a következőn keresztül:


Munkamenet- és állapotkezelés a ASP.NET Core-ban

Rick Anderson, Kirk Larkin és Diana LaRose

A HTTP állapot nélküli protokoll. Alapértelmezés szerint a HTTP-kérések olyan független üzenetek, amelyek nem őrzik meg a felhasználói értékeket. Ez a cikk számos módszert ismertet a felhasználói adatok kérések közötti megőrzésére.

Az Blazor ebben a cikkben szereplő útmutatást hozzáadó vagy felülíró állapotkezelési útmutatásért tekintse meg ASP.NET Alapszintű Blazor állapotkezelés áttekintését.

Állapotkezelés

Az állapot több módszerrel is tárolható. Az egyes megközelítéseket a cikk későbbi részében ismertetjük.

Tárolási megközelítés Tárolási mechanizmus
Cookies HTTP cookie Tartalmazhat kiszolgálóoldali alkalmazáskóddal tárolt adatokat is.
Munkamenet állapota HTTP-cookie-k és kiszolgálóoldali alkalmazáskód
TempData HTTP-cookie-k vagy munkamenet-állapot
Lekérdezési sztringek HTTP-lekérdezési karakterláncok
Rejtett mezők HTTP-űrlapmezők
HttpContext.Items Kiszolgálóoldali alkalmazáskód
Cache Kiszolgálóoldali alkalmazáskód

SignalR/Blazor Server és HTTP környezetalapú állapotkezelés

SignalR az alkalmazások nem használhatnak munkamenet-állapotot és más állapotkezelési módszereket, amelyek stabil HTTP-környezetre támaszkodnak az információk tárolásához. SignalRaz alkalmazások a hubon tárolhatják a kapcsolatonkénti állapototContext.Items. További információkért és az alkalmazások alternatív állapotkezelési megközelítéseiért Blazor Server tekintse meg ASP.NET Core-állapotkezelés Blazor áttekintését és ASP.NET Core-kiszolgálóoldali Blazor állapotkezelést.

Cookies

A cookie-k a kérések között tárolják az adatokat. Mivel a cookie-k minden kéréssel együtt érkeznek, méretüket a lehető legkisebbre kell csökkenteni. Ideális esetben csak egy azonosítót kell tárolni cookie az alkalmazás által tárolt adatokkal együtt. A legtöbb böngésző 4096 bájtra korlátozza cookie a méretet. Az egyes tartományokhoz csak korlátozott számú cookie érhető el.

Mivel a cookie-kat illetéktelen beavatkozásnak kell alávetni, az alkalmazásnak ellenőriznie kell őket. A cookie-kat a felhasználók törölhetik, és az ügyfeleken lejárhatnak. A cookie-k azonban általában a legtartósabb adatmegőrzési forma az ügyfélen.

A cookie-kat gyakran használják személyre szabáshoz, ahol a tartalom egy ismert felhasználó számára van testre szabva. A felhasználót csak a legtöbb esetben azonosítják, és nem hitelesítik. A cookie felhasználó nevét, fióknevét vagy egyedi felhasználói azonosítóját, például GUID azonosítóját tárolhatja. A cookie a felhasználó személyre szabott beállításainak elérésére használható, például a kedvelt webhely háttérszínéhez.

Tekintse meg az Európai Unió általános adatvédelmi rendeletét (GDPR) a cookie-k kibocsátása és az adatvédelmi aggályok kezelése során. További információ: Általános adatvédelmi rendelet (GDPR) támogatása a ASP.NET Core-ban.

Munkamenet állapota

A munkamenet-állapot egy ASP.NET Alapvető forgatókönyv a felhasználói adatok tárolásához, miközben a felhasználó egy webalkalmazásban tallózik. A munkamenet-állapot az alkalmazás által fenntartott tárolót használja az adatok ügyféltől érkező kérések közötti megőrzéséhez. A munkamenet-adatokat egy gyorsítótár tárolja és rövid élettartamú adatnak tekintik. A webhelynek továbbra is működnie kell a munkamenet adatai nélkül. A kritikus alkalmazásadatokat a felhasználói adatbázisban kell tárolni, és a munkamenetben csak teljesítményoptimalizálásként kell gyorsítótárazni.

A SignalR alkalmazásokban a munkamenet nem támogatott, mert egy SignalR központ a HTTP-környezetétől függetlenül is futtatható. Ez például akkor fordulhat elő, ha egy központ egy hosszú lekérdezési kérést tart nyitva a kérelem HTTP-környezetének élettartamán túl.

ASP.NET Core úgy tartja karban a munkamenet állapotát, hogy az ügyfélnek megad egy munkamenet-azonosítót tartalmazó cookie. A cookie munkamenet azonosítója:

  • A rendszer minden kéréssel elküldi az alkalmazásnak.
  • Az alkalmazás a munkamenet adatainak lekérésére használja.

A munkamenet állapota a következő viselkedéseket mutatja:

  • A munkamenet cookie a böngészőre jellemző. A munkamenetek nem lesznek megosztva a böngészők között.
  • A munkamenet-cookie-k a böngésző munkamenetének befejeződésekor törlődnek.
  • Ha lejárt cookie munkamenet érkezik, egy új munkamenet jön létre, amely ugyanazt a munkamenetet cookiehasználja.
  • Az üres munkamenetek nem kerülnek megőrzésre. A munkamenetnek legalább egy olyan értékkel kell rendelkeznie, amely a munkamenetet a kérések között megőrzi. Ha egy munkamenet nem marad meg, a rendszer minden új kéréshez létrehoz egy új munkamenet-azonosítót.
  • Az alkalmazás az utolsó kérés után korlátozott ideig megtart egy munkamenetet. Az alkalmazás vagy beállítja a munkamenet időtúllépését, vagy az alapértelmezett 20 perces értéket használja. A munkamenet-állapot ideális a felhasználói adatok tárolásához:
    • Ez egy adott munkamenetre vonatkozik.
    • Ahol az adatok nem igényelnek állandó tárolást a munkamenetek között.
  • A munkamenet-adatok a végrehajtás meghívásakor vagy a munkamenet lejáratakor törlődnek ISession.Clear .
  • Nincs alapértelmezett mechanizmus az alkalmazáskód számára, hogy értesüljön az ügyfélböngésző bezárásáról, vagy ha a munkamenet cookie törölve lett vagy lejárt a kliensoldalon.
  • A munkamenet-állapot cookie-k alapértelmezés szerint nem nélkülözhetetlenek. A munkamenet állapota nem működőképes, hacsak a webhely látogatója nem engedélyezi a nyomkövetést. További információ: Általános adatvédelmi rendelet (GDPR) támogatása a ASP.NET Core-ban.
  • Megjegyzés: A ASP.NET-keretrendszer nem helyettesíti a cookie nélküli munkamenet funkciót, mert nem biztonságosnak minősül, és munkamenet-rögzítési támadásokat okozhat.

Warning

Ne tárolja a bizalmas adatokat munkamenet-állapotban. Előfordulhat, hogy a felhasználó nem zárja be a böngészőt, és nem törli a munkamenetet cookie. Egyes böngészők érvényes munkamenet-cookie-kat tartanak fenn a böngészőablakokban. Előfordulhat, hogy egy munkamenet nem korlátozódik egyetlen felhasználóra. Előfordulhat, hogy a következő felhasználó ugyanazzal a munkamenettel cookieböngészi az alkalmazást.

A memóriabeli gyorsítótár-szolgáltató a munkamenet-adatokat annak a kiszolgálónak a memóriájában tárolja, ahol az alkalmazás található. Kiszolgálófarm esetén:

  • A ragadós munkamenetek használatával minden munkamenetet egy adott alkalmazáspéldányhoz köthet egy adott kiszolgálón. Az Azure App Service alapértelmezés szerint ragadós munkameneteket biztosít az Application Request Routing (ARR) használatával. A ragadós munkamenetek azonban hatással lehetnek a méretezhetőségre, és bonyolíthatják a webalkalmazás-frissítéseket. Jobb módszer egy Redis, SQL Server vagy Azure Postgres elosztott gyorsítótár használata, amely nem igényel ragadós munkameneteket. További információért lásd a(z) ASP.NET Core Elosztott gyorsítótárazás .
  • A munkamenet cookie titkosítása a következőn keresztül történik IDataProtector: . Az adatvédelemnek megfelelően konfigurálva kell lennie a munkamenet-cookie-k olvasásához minden gépen. További információ: ASP.NET Alapvető adatvédelmi áttekintés és kulcstároló-szolgáltatók.

Munkamenet állapotának konfigurálása

A munkamenet-állapot kezelésére szolgáló köztes szoftver szerepel a keretrendszerben. A munkamenet köztes szoftverének Program.cs engedélyezéséhez a következőket kell tartalmaznia:

  • Bármelyik memória gyorsítótár. Az IDistributedCache implementáció háttértárként szolgál a munkamenetekhez. További információért lásd a(z) ASP.NET Core Elosztott gyorsítótárazás .
  • Hívás a AddSession
  • Hívás a UseSession

Az alábbi kód bemutatja, hogyan állíthatja be a memóriabeli munkamenet-szolgáltatót a következő alapértelmezett memóriabeli implementációval IDistributedCache:

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();

Az előző kód rövid időtúllépést állít be a tesztelés egyszerűsítése érdekében.

A köztes szoftver sorrendje fontos. Hívja UseSession után UseRouting, és előtte MapRazorPages és MapDefaultControllerRoute. Lásd : Middleware Ordering.

A HttpContext.Session a munkamenet-állapot konfigurálása után érhető el.

HttpContext.Session nem érhető el, mielőtt UseSession meghívták volna.

Nem hozható létre új munkamenet új munkamenettel cookie , miután az alkalmazás megkezdte az írást a válaszfolyamba. A kivétel a webkiszolgáló naplójában van rögzítve, és nem jelenik meg a böngészőben.

Munkamenet-állapot aszinkron betöltése

A ASP.NET Core alapértelmezett munkamenet-szolgáltatója csak akkor tölti be a munkamenetrekordokat az alapul szolgáló IDistributedCache háttértárból aszinkron módon, ha a ISession.LoadAsync metódust explicit módon hívják meg az TryGetValue, Setvagy Remove metódusok előtt. Ha LoadAsync nincs először meghívva, a mögöttes munkamenetrekord szinkron módon töltődik be, ami nagy léptékben teljesítménycsökkenést okozhat.

Ha azt szeretné, hogy az alkalmazások kényszerítsék ezt a mintát, csomagolja be a DistributedSessionStore és DistributedSession implementációkat olyan verziókkal, amelyek kivételt dobnak, ha a LoadAsync metódust nem hívták meg a TryGetValue, Set vagy Remove előtt. Regisztrálja a becsomagolt verziókat a szolgáltatástárolóban.

Munkamenet beállításai

A munkamenet alapértelmezéseinek felülbírálásához használja a következőt SessionOptions: .

Option Description
Cookie Meghatározza azokat a beállításokat, amelyeket a cookie létrehozásához használnak. Namealapértelmezett értéke (SessionDefaults.CookieName.AspNetCore.Session). Pathalapértelmezett értéke (SessionDefaults.CookiePath/). SameSitealapértelmezett értéke (SameSiteMode.Lax1). HttpOnly alapértelmezés szerint true. IsEssential alapértelmezés szerint false.
IdleTimeout Ez IdleTimeout azt jelzi, hogy mennyi ideig lehet tétlen a munkamenet, mielőtt annak tartalma megszűnik. Minden munkamenet elérése visszaállítja az időtúllépést. Ez a beállítás csak a munkamenet tartalmára vonatkozik, nem a cookie-ra. Az alapértelmezett érték 20 perc.
IOTimeout A munkamenet tárolóból való betöltésére vagy visszamentésére engedélyezett maximális idő. Ez a beállítás csak az aszinkron műveletekre vonatkozhat. Ez az időtúllépés letiltható a következővel InfiniteTimeSpan. Az alapértelmezett érték 1 perc.

A munkamenet egy cookie-t használ a kérések nyomon követésére és azonosítására egyetlen böngészőből. Alapértelmezés szerint ennek a cookie a neve .AspNetCore.Session, és az / elérési utat használja. Mivel az cookie alapértelmezett beállítás nem ad meg tartományt, a lap ügyféloldali szkriptje számára nem elérhető (mivel a HttpOnly alapértelmezett a true).

Az cookie munkamenet alapértelmezéseinek felülbírálásához használja a következőt: 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();

Az alkalmazás a IdleTimeout tulajdonság használatával határozza meg, hogy mennyi ideig lehet tétlen egy munkamenet, mielőtt a kiszolgáló gyorsítótárában lévő tartalma megszűnik. Ez a tulajdonság független a lejárattól cookie . A Session Middleware-ben átmenő összes kérés újraindítja az időtúllépést.

A munkamenet állapota nem zárolva. Ha két kérés egyszerre kísérli meg módosítani egy munkamenet tartalmát, az utolsó kérés felülbírálja az elsőt. Session koherens munkamenetként van implementálva, ami azt jelenti, hogy az összes tartalom együtt van tárolva. Ha két kérés különböző munkamenet-értékeket próbál módosítani, az utolsó kérés felülírhatja az első munkamenet-módosításokat.

Munkamenet-értékek beállítása és lekérése

A munkamenet állapota a Razor Pages PageModel osztályból vagy az MVC Controller osztályból HttpContext.Sessionérhető el. Ez egy ISession implementáció.

Az ISession implementáció számos bővítménymetelyt biztosít az egész szám és a sztringértékek beállításához és lekéréséhez. A kiterjesztési metódusok a Microsoft.AspNetCore.Http névtérben találhatók.

ISession bővítménymetelyek:

Az alábbi példa lekéri a IndexModel.SessionKeyName kulcs munkamenet-értékét (_Name a mintaalkalmazásban) a Razor Pages lapon:

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

...

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

Az alábbi példa egy egész szám és egy sztring beállítását és lekérését mutatja be:

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);
    }
}

Az alábbi korrektúra megjeleníti a munkamenet-értékeket egy Razor lapon:

@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>


Az elosztott gyorsítótár-forgatókönyvek engedélyezéséhez minden munkamenet-adatot szerializálni kell, még akkor is, ha a memóriabeli gyorsítótárat használja. A sztring- és egész szám szerializálók az ISession-hoz tartozó kiterjesztéses metódusok által biztosítva vannak. Az összetett típusokat a felhasználónak szerializálnia kell egy másik mechanizmus, például a JSON használatával.

Az objektumok szerializálásához használja az alábbi mintakódot:

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);
    }
}

Az alábbi példa bemutatja, hogyan állíthat be és kérhet le szerializálható objektumot az SessionExtensions osztálysal:

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));

        }
    }
}

Warning

Az élő objektumok munkamenetben való tárolását körültekintően kell használni, mivel számos probléma léphet fel szerializált objektumokkal. További információ: A munkamenetek számára engedélyezni kell az objektumok tárolását (dotnet/aspnetcore #18159).

TempData

ASP.NET Core a Pages Razor vagy a Controller TempDatalapokat teszi elérhetővé. Ez a tulajdonság addig tárolja az adatokat, amíg egy másik kérés nem olvassa be. A Keep(String) és a Peek(sztring) metódussal a kérelem végén törlés nélkül vizsgálhatja meg az adatokat. Megjelöli a szótár összes elemét a megőrzés érdekében. TempData van:

  • Az átirányításhoz akkor hasznos, ha több kéréshez is szükség van adatokra.
  • TempData szolgáltatók által implementálva, akik cookie-kat vagy munkamenet-állapotot használnak.

TempData-minták

Vegye figyelembe a következő oldalt, amely létrehoz egy ügyfelet:

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");
    }
}

A következő oldal jelenik meg TempData["Message"]:

@page
@model IndexModel

<h1>Peek Contacts</h1>

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

@*Content removed for brevity.*@

Az előző jelölésben a kérelem végén TempData["Message"] törlődik, mert használatban van. Az oldal frissítése megjeleníti a TempData["Message"] tartalmát.

A következő jelölés hasonló az előző kódhoz, de a Keep használatával megőrzi a kérés végén lévő adatokat.

@page
@model IndexModel

<h1>Contacts Keep</h1>

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

@*Content removed for brevity.*@

Az IndexPeek és az IndexKeep lapok közti navigálás nem fogja törölni a TempData["Message"].

A következő kód jelenik meg: TempData["Message"], de a kérés végén a TempData["Message"] törlődik.

@page
@model IndexModel

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

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

@*Content removed for brevity.*@

TempData-szolgáltatók

A cookie-based TempData szolgáltató alapértelmezés szerint a TempData cookie-kban való tárolására szolgál.

Az cookie adatok titkosítva IDataProtectorlesznek, kódolva Base64UrlTextEncoder, majd adattömbbe ágyazva. A maximális cookie méret kisebb, mint 4096 bájt a titkosítás és az adattömbelés miatt. Az cookie adatok nincsenek tömörítve, mert a titkosított adatok tömörítése biztonsági problémákhoz, például támadásokhoz CRIMEBREACH vezethet. Az cookie alapú TempData szolgáltatóval kapcsolatos további információkért lásd CookieTempDataProvider.

TempData-szolgáltató kiválasztása

A TempData-szolgáltató kiválasztása több szempontot is magában foglal, például:

  • Az alkalmazás már használ munkamenet-állapotot? Ha igen, a TempData-szolgáltató munkamenet-állapotának használata nem jár további költségekkel az alkalmazás számára az adatok méretén túl.
  • Az alkalmazás csak takarékosan használja a TempData-t viszonylag kis mennyiségű, legfeljebb 500 bájtnyi adathoz? Ha igen, a cookie TempData-szolgáltató kis költséggel egészíti ki a TempData-t tartalmazó kérelmeket. Ha nem, a TempData munkamenet-állapot szolgáltató hasznos lehet, hogy elkerülje a nagy mennyiségű adat körbejárását az egyes kérések során, amíg a TempData felhasználásra kerül.
  • Az alkalmazás több kiszolgálón futó kiszolgálófarmban fut? Ha igen, nincs szükség további konfigurációra a cookie TempData-szolgáltató adatvédelemen kívüli használatához. További információ: ASP.NET Alapvető adatvédelmi áttekintés és kulcstároló-szolgáltatók.

A legtöbb webügyfél, például a webböngésző korlátozza az egyes cookie fájlok maximális méretét és a cookie-k teljes számát. A TempData-szolgáltató használatakor cookie ellenőrizze, hogy az alkalmazás nem lépi-e túl ezeket a korlátokat. Vegye figyelembe az adatok teljes méretét. Figyelembe kell venni a titkosítás és az cookie adattömb-készítés miatti méretnövekedést.

A TempData-szolgáltató konfigurálása

A cookie-based TempData szolgáltató alapértelmezés szerint engedélyezve van.

A munkamenet-alapú TempData-szolgáltató engedélyezéséhez használja a AddSessionStateTempDataProvider bővítménymetódust. Csak egyetlen AddSessionStateTempDataProvider hívásra van szükség.

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();

Lekérdezési karakterláncok

Az új kérés lekérdezési sztringjének hozzáadásával korlátozott mennyiségű adat továbbítható az egyik kérelemből a másikba. Ez akkor hasznos, ha állandó módon rögzíti az állapotot, amely lehetővé teszi a beágyazott állapotra mutató hivatkozások megosztását e-mailben vagy közösségi hálózatokon keresztül. Mivel az URL-lekérdezési sztringek nyilvánosak, ne használjon lekérdezési sztringeket bizalmas adatokhoz.

A nem szándékos megosztás mellett, beleértve a lekérdezési sztringekben lévő adatokat is, az alkalmazás a helyek közötti kérelemhamisítási (CSRF-) támadásoknak is kiteheti az alkalmazást. Minden megőrzött munkamenet-állapotnak védelmet kell nyújtania a CSRF-támadások ellen. További információért lásd: Az ASP.NET Core alkalmazásban történő helyek közötti kéréshamisítás (XSRF/CSRF) elleni támadások megakadályozása.

Rejtett mezők

Az adatok menthetők rejtett űrlapmezőkbe, és a következő kérelemben közzétehetők. Ez gyakori a többoldalas űrlapokon. Mivel az ügyfél esetleg illetéktelenül módosíthatja az adatokat, az alkalmazásnak mindig újra kell értékelnie a rejtett mezőkben tárolt adatokat.

HttpContext.Items

A HttpContext.Items gyűjtemény egyetlen kérés feldolgozása során tárolja az adatokat. A rendszer a kérés feldolgozása után elveti a gyűjtemény tartalmát. A Items gyűjteményt gyakran arra használják, hogy lehetővé tegyék az összetevők vagy köztes szoftverek számára a kommunikációt, amikor a kérés során különböző időpontokban működnek, és nincs közvetlen mód a paraméterek átadására.

A következő példában a köztes szoftver hozzáadja isVerified a Items kollekcióhoz.

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();

A csak egyetlen alkalmazásban használt köztes szoftverek esetében nem valószínű, hogy a rögzített string kulcs használata kulcsütközést okozna. A kulcsok ütközésének object elkerülése érdekében azonban elemkulcsként is használható. Ez a megközelítés különösen hasznos az alkalmazások között megosztott köztes szoftverek esetében, és azzal az előnnyel jár, hogy megszünteti a kódban található kulcssztringek használatát. Az alábbi példa bemutatja, hogyan használható egy object köztes szoftverosztályban definiált kulcs:

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>();
    }
}

Más kód a köztes szoftverosztály által közzétett kulccsal érheti el a tárolt HttpContext.Items értéket:

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

A gyorsítótárazás hatékony módja az adatok tárolásának és lekérésének. Az alkalmazás szabályozhatja a gyorsítótárazott elemek élettartamát. További információért lásd: Válasz gyorsítótárazása az ASP.NET Core-ban.

A gyorsítótárazott adatok nincsenek hozzárendelve egy adott kéréshez, felhasználóhoz vagy munkamenethez. Ne gyorsítótárazza azokat a felhasználóspecifikus adatokat, amelyeket más felhasználói kérések kérhetnek le.

Az alkalmazásszintű adatok gyorsítótárazásához lásd: Gyorsítótár a memóriában ASP.NET Core-ban.

Munkamenet állapotának ellenőrzése

Az ISession.IsAvailable az átmeneti hibák ellenőrzésére szolgál. A IsAvailable hívása a munkamenet köztes szoftverének futtatása előtt egy InvalidOperationException-t idéz elő.

A munkamenetek rendelkezésre állásának teszteléséhez használhatóak az HttpContext.Features.Get<ISessionFeature>()?.Session != null kódtárak.

Gyakori hibák

Ha a munkamenet köztes szoftvere nem őriz meg egy munkamenetet:

  • A köztes szoftver naplózza a kivételt, és a kérés a szokásos módon folytatódik.
  • Ez kiszámíthatatlan viselkedéshez vezet.

A munkamenet köztes szoftvere nem tudja tárolni a munkamenetet, ha a háttértár nem érhető el. A felhasználó például munkamenet közben tárol egy bevásárlókocsit. A felhasználó hozzáad egy elemet a kosárhoz, de a véglegesítés sikertelen. Az alkalmazás nem tud a hibáról, ezért jelenti a felhasználónak, hogy az elemet hozzáadták a kosárhoz, ami nem igaz.

A hibák ellenőrzésének ajánlott módszere az, hogy hívja meg a await feature.Session.CommitAsync-t, amikor az alkalmazás befejezi a munkamenetbe való írást. CommitAsync kivételt eredményez, ha a háttértár nem érhető el. Ha CommitAsync nem sikerül, az alkalmazás feldolgozhatja a kivételt. LoadAsync azonos feltételek mellett hibát dob, amikor az adattár nem elérhető.

További erőforrások

Mintakód megtekintése vagy letöltése (hogyan töltsd le)

ASP.NET Core üzemeltetése egy webfarmban

Rick Anderson, Kirk Larkin és Diana LaRose

A HTTP állapot nélküli protokoll. Alapértelmezés szerint a HTTP-kérések olyan független üzenetek, amelyek nem őrzik meg a felhasználói értékeket. Ez a cikk számos módszert ismertet a felhasználói adatok kérések közötti megőrzésére.

Mintakód megtekintése vagy letöltése (hogyan töltsd le)

Állapotkezelés

Az állapot több módszerrel is tárolható. Az egyes megközelítéseket a cikk későbbi részében ismertetjük.

Tárolási megközelítés Tárolási mechanizmus
Cookies HTTP cookie Tartalmazhat kiszolgálóoldali alkalmazáskóddal tárolt adatokat is.
Munkamenet állapota HTTP-cookie-k és kiszolgálóoldali alkalmazáskód
TempData HTTP-cookie-k vagy munkamenet-állapot
Lekérdezési sztringek HTTP-lekérdezési karakterláncok
Rejtett mezők HTTP-űrlapmezők
HttpContext.Items Kiszolgálóoldali alkalmazáskód
Cache Kiszolgálóoldali alkalmazáskód

SignalR/Blazor Server és HTTP környezetalapú állapotkezelés

SignalR az alkalmazások nem használhatnak munkamenet-állapotot és más állapotkezelési módszereket, amelyek stabil HTTP-környezetre támaszkodnak az információk tárolásához. SignalRaz alkalmazások a hubon tárolhatják a kapcsolatonkénti állapototContext.Items. További információkért és az alkalmazások alternatív állapotkezelési megközelítéseiért Blazor Server tekintse meg ASP.NET Core-állapotkezelés Blazor áttekintését és ASP.NET Core-kiszolgálóoldali Blazor állapotkezelést.

Cookies

A cookie-k a kérések között tárolják az adatokat. Mivel a cookie-k minden kéréssel együtt érkeznek, méretüket a lehető legkisebbre kell csökkenteni. Ideális esetben csak egy azonosítót kell tárolni cookie az alkalmazás által tárolt adatokkal együtt. A legtöbb böngésző 4096 bájtra korlátozza cookie a méretet. Az egyes tartományokhoz csak korlátozott számú cookie érhető el.

Mivel a cookie-kat illetéktelen beavatkozásnak kell alávetni, az alkalmazásnak ellenőriznie kell őket. A cookie-kat a felhasználók törölhetik, és az ügyfeleken lejárhatnak. A cookie-k azonban általában a legtartósabb adatmegőrzési forma az ügyfélen.

A cookie-kat gyakran használják személyre szabáshoz, ahol a tartalom egy ismert felhasználó számára van testre szabva. A felhasználót csak a legtöbb esetben azonosítják, és nem hitelesítik. A cookie felhasználó nevét, fióknevét vagy egyedi felhasználói azonosítóját, például GUID azonosítóját tárolhatja. A cookie a felhasználó személyre szabott beállításainak elérésére használható, például a kedvelt webhely háttérszínéhez.

Tekintse meg az Európai Unió általános adatvédelmi rendeletét (GDPR) a cookie-k kibocsátása és az adatvédelmi aggályok kezelése során. További információ: Általános adatvédelmi rendelet (GDPR) támogatása a ASP.NET Core-ban.

Munkamenet állapota

A munkamenet-állapot egy ASP.NET Alapvető forgatókönyv a felhasználói adatok tárolásához, miközben a felhasználó egy webalkalmazásban tallózik. A munkamenet-állapot az alkalmazás által fenntartott tárolót használja az adatok ügyféltől érkező kérések közötti megőrzéséhez. A munkamenet-adatokat egy gyorsítótár tárolja és rövid élettartamú adatnak tekintik. A webhelynek továbbra is működnie kell a munkamenet adatai nélkül. A kritikus alkalmazásadatokat a felhasználói adatbázisban kell tárolni, és a munkamenetben csak teljesítményoptimalizálásként kell gyorsítótárazni.

A SignalR alkalmazásokban a munkamenet nem támogatott, mert egy SignalR központ a HTTP-környezetétől függetlenül is futtatható. Ez például akkor fordulhat elő, ha egy központ egy hosszú lekérdezési kérést tart nyitva a kérelem HTTP-környezetének élettartamán túl.

ASP.NET Core úgy tartja karban a munkamenet állapotát, hogy az ügyfélnek megad egy munkamenet-azonosítót tartalmazó cookie. A cookie munkamenet azonosítója:

  • A rendszer minden kéréssel elküldi az alkalmazásnak.
  • Az alkalmazás a munkamenet adatainak lekérésére használja.

A munkamenet állapota a következő viselkedéseket mutatja:

  • A munkamenet cookie a böngészőre jellemző. A munkamenetek nem lesznek megosztva a böngészők között.
  • A munkamenet-cookie-k a böngésző munkamenetének befejeződésekor törlődnek.
  • Ha lejárt cookie munkamenet érkezik, egy új munkamenet jön létre, amely ugyanazt a munkamenetet cookiehasználja.
  • Az üres munkamenetek nem kerülnek megőrzésre. A munkamenetnek legalább egy olyan értékkel kell rendelkeznie, amely a munkamenetet a kérések között megőrzi. Ha egy munkamenet nem marad meg, a rendszer minden új kéréshez létrehoz egy új munkamenet-azonosítót.
  • Az alkalmazás az utolsó kérés után korlátozott ideig megtart egy munkamenetet. Az alkalmazás vagy beállítja a munkamenet időtúllépését, vagy az alapértelmezett 20 perces értéket használja. A munkamenet-állapot ideális a felhasználói adatok tárolásához:
    • Ez egy adott munkamenetre vonatkozik.
    • Ahol az adatok nem igényelnek állandó tárolást a munkamenetek között.
  • A munkamenet-adatok a végrehajtás meghívásakor vagy a munkamenet lejáratakor törlődnek ISession.Clear .
  • Nincs alapértelmezett mechanizmus az alkalmazáskód számára, hogy értesüljön az ügyfélböngésző bezárásáról, vagy ha a munkamenet cookie törölve lett vagy lejárt a kliensoldalon.
  • A munkamenet-állapot cookie-k alapértelmezés szerint nem nélkülözhetetlenek. A munkamenet állapota nem működőképes, hacsak a webhely látogatója nem engedélyezi a nyomkövetést. További információ: Általános adatvédelmi rendelet (GDPR) támogatása a ASP.NET Core-ban.

Warning

Ne tárolja a bizalmas adatokat munkamenet-állapotban. Előfordulhat, hogy a felhasználó nem zárja be a böngészőt, és nem törli a munkamenetet cookie. Egyes böngészők érvényes munkamenet-cookie-kat tartanak fenn a böngészőablakokban. Előfordulhat, hogy egy munkamenet nem korlátozódik egyetlen felhasználóra. Előfordulhat, hogy a következő felhasználó ugyanazzal a munkamenettel cookieböngészi az alkalmazást.

A memóriabeli gyorsítótár-szolgáltató a munkamenet-adatokat annak a kiszolgálónak a memóriájában tárolja, ahol az alkalmazás található. Kiszolgálófarm esetén:

  • A ragadós munkamenetek használatával minden munkamenetet egy adott alkalmazáspéldányhoz köthet egy adott kiszolgálón. Az Azure App Service alapértelmezés szerint ragadós munkameneteket biztosít az Application Request Routing (ARR) használatával. A ragadós munkamenetek azonban hatással lehetnek a méretezhetőségre, és bonyolíthatják a webalkalmazás-frissítéseket. Jobb módszer egy Redis, SQL Server vagy Azure Postgres elosztott gyorsítótár használata, amely nem igényel ragadós munkameneteket. További információért lásd a(z) ASP.NET Core Elosztott gyorsítótárazás .
  • A munkamenet cookie titkosítása a következőn keresztül történik IDataProtector: . Az adatvédelemnek megfelelően konfigurálva kell lennie a munkamenet-cookie-k olvasásához minden gépen. További információ: ASP.NET Alapvető adatvédelmi áttekintés és kulcstároló-szolgáltatók.

Munkamenet állapotának konfigurálása

A Microsoft.AspNetCore.Session csomag:

  • A keretrendszer implicit módon tartalmazza.
  • Köztes szoftver a munkamenet állapotának kezeléséhez.

A munkamenet köztes szoftverének Startup engedélyezéséhez a következőket kell tartalmaznia:

  • Bármelyik memória gyorsítótár. Az IDistributedCache implementáció háttértárként szolgál a munkamenetekhez. További információért lásd a(z) ASP.NET Core Elosztott gyorsítótárazás .
  • Hívás AddSession a ConfigureServices-ben.
  • Hívás UseSession a Configure-ben.

Az alábbi kód bemutatja, hogyan állíthatja be a memóriabeli munkamenet-szolgáltatót a következő alapértelmezett memóriabeli implementációval IDistributedCache:

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();
        });
    }
}

Az előző kód rövid időtúllépést állít be a tesztelés egyszerűsítése érdekében.

A köztes szoftver sorrendje fontos. Hívd UseSessionUseRouting után és UseEndpoints előtt. Lásd : Middleware Ordering.

A HttpContext.Session a munkamenet-állapot konfigurálása után érhető el.

HttpContext.Session nem érhető el, mielőtt UseSession meghívták volna.

Nem hozható létre új munkamenet új munkamenettel cookie , miután az alkalmazás megkezdte az írást a válaszfolyamba. A kivétel a webkiszolgáló naplójában van rögzítve, és nem jelenik meg a böngészőben.

Munkamenet-állapot aszinkron betöltése

A ASP.NET Core alapértelmezett munkamenet-szolgáltatója csak akkor tölti be a munkamenetrekordokat az alapul szolgáló IDistributedCache háttértárból aszinkron módon, ha a ISession.LoadAsync metódust explicit módon hívják meg az TryGetValue, Setvagy Remove metódusok előtt. Ha LoadAsync nincs először meghívva, a mögöttes munkamenetrekord szinkron módon töltődik be, ami nagy léptékben teljesítménycsökkenést okozhat.

Ha azt szeretné, hogy az alkalmazások kényszerítsék ezt a mintát, csomagolja be a DistributedSessionStore és DistributedSession implementációkat olyan verziókkal, amelyek kivételt dobnak, ha a LoadAsync metódust nem hívták meg a TryGetValue, Set vagy Remove előtt. Regisztrálja a becsomagolt verziókat a szolgáltatástárolóban.

Munkamenet beállításai

A munkamenet alapértelmezéseinek felülbírálásához használja a következőt SessionOptions: .

Option Description
Cookie Meghatározza azokat a beállításokat, amelyeket a cookie létrehozásához használnak. Namealapértelmezett értéke (SessionDefaults.CookieName.AspNetCore.Session). Pathalapértelmezett értéke (SessionDefaults.CookiePath/). SameSitealapértelmezett értéke (SameSiteMode.Lax1). HttpOnly alapértelmezés szerint true. IsEssential alapértelmezés szerint false.
IdleTimeout Ez IdleTimeout azt jelzi, hogy mennyi ideig lehet tétlen a munkamenet, mielőtt annak tartalma megszűnik. Minden munkamenet elérése visszaállítja az időtúllépést. Ez a beállítás csak a munkamenet tartalmára vonatkozik, nem a cookie-ra. Az alapértelmezett érték 20 perc.
IOTimeout A munkamenet tárolóból való betöltésére vagy visszamentésére engedélyezett maximális idő. Ez a beállítás csak az aszinkron műveletekre vonatkozhat. Ez az időtúllépés letiltható a következővel InfiniteTimeSpan. Az alapértelmezett érték 1 perc.

A munkamenet egy cookie-t használ a kérések nyomon követésére és azonosítására egyetlen böngészőből. Alapértelmezés szerint ennek a cookie a neve .AspNetCore.Session, és az / elérési utat használja. Mivel az cookie alapértelmezett beállítás nem ad meg tartományt, a lap ügyféloldali szkriptje számára nem elérhető (mivel a HttpOnly alapértelmezett a true).

Az cookie munkamenet alapértelmezéseinek felülbírálásához használja a következőt: 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();
}

Az alkalmazás a IdleTimeout tulajdonság használatával határozza meg, hogy mennyi ideig lehet tétlen egy munkamenet, mielőtt a kiszolgáló gyorsítótárában lévő tartalma megszűnik. Ez a tulajdonság független a lejárattól cookie . A Session Middleware-ben átmenő összes kérés újraindítja az időtúllépést.

A munkamenet állapota nem zárolva. Ha két kérés egyszerre kísérli meg módosítani egy munkamenet tartalmát, az utolsó kérés felülbírálja az elsőt. Session koherens munkamenetként van implementálva, ami azt jelenti, hogy az összes tartalom együtt van tárolva. Ha két kérés különböző munkamenet-értékeket próbál módosítani, az utolsó kérés felülírhatja az első munkamenet-módosításokat.

Munkamenet-értékek beállítása és lekérése

A munkamenet állapota a Razor Pages PageModel osztályból vagy az MVC Controller osztályból HttpContext.Sessionérhető el. Ez egy ISession implementáció.

Az ISession implementáció számos bővítménymetelyt biztosít az egész szám és a sztringértékek beállításához és lekéréséhez. A kiterjesztési metódusok a Microsoft.AspNetCore.Http névtérben találhatók.

ISession bővítménymetelyek:

Az alábbi példa lekéri a IndexModel.SessionKeyName kulcs munkamenet-értékét (_Name a mintaalkalmazásban) a Razor Pages lapon:

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

...

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

Az alábbi példa egy egész szám és egy sztring beállítását és lekérését mutatja be:

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);

Az elosztott gyorsítótár-forgatókönyvek engedélyezéséhez minden munkamenet-adatot szerializálni kell, még akkor is, ha a memóriabeli gyorsítótárat használja. A sztring- és egész szám szerializálók az ISession-hoz tartozó kiterjesztéses metódusok által biztosítva vannak. Az összetett típusokat a felhasználónak szerializálnia kell egy másik mechanizmus, például a JSON használatával.

Az objektumok szerializálásához használja az alábbi mintakódot:

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);
    }
}

Az alábbi példa bemutatja, hogyan állíthat be és kérhet le szerializálható objektumot az SessionExtensions osztálysal:

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

TempData

ASP.NET Core a Pages Razor vagy a Controller TempDatalapokat teszi elérhetővé. Ez a tulajdonság addig tárolja az adatokat, amíg egy másik kérés nem olvassa be. A Keep(String) és a Peek(sztring) metódussal a kérelem végén törlés nélkül vizsgálhatja meg az adatokat. Megjelöli a szótár összes elemét a megőrzés érdekében. TempData van:

  • Az átirányításhoz akkor hasznos, ha több kéréshez is szükség van adatokra.
  • TempData szolgáltatók által implementálva, akik cookie-kat vagy munkamenet-állapotot használnak.

TempData-minták

Vegye figyelembe a következő oldalt, amely létrehoz egy ügyfelet:

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");
    }
}

A következő oldal jelenik meg TempData["Message"]:

@page
@model IndexModel

<h1>Peek Contacts</h1>

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

@*Content removed for brevity.*@

Az előző jelölésben a kérelem végén TempData["Message"] törlődik, mert használatban van. Az oldal frissítése megjeleníti a TempData["Message"] tartalmát.

A következő jelölés hasonló az előző kódhoz, de a Keep használatával megőrzi a kérés végén lévő adatokat.

@page
@model IndexModel

<h1>Contacts Keep</h1>

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

@*Content removed for brevity.*@

Az IndexPeek és az IndexKeep lapok közti navigálás nem fogja törölni a TempData["Message"].

A következő kód jelenik meg: TempData["Message"], de a kérés végén a TempData["Message"] törlődik.

@page
@model IndexModel

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

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

@*Content removed for brevity.*@

TempData-szolgáltatók

A cookie-based TempData szolgáltató alapértelmezés szerint a TempData cookie-kban való tárolására szolgál.

Az cookie adatok titkosítva IDataProtectorlesznek, kódolva Base64UrlTextEncoder, majd adattömbbe ágyazva. A maximális cookie méret kisebb, mint 4096 bájt a titkosítás és az adattömbelés miatt. Az cookie adatok nincsenek tömörítve, mert a titkosított adatok tömörítése biztonsági problémákhoz, például támadásokhoz CRIMEBREACH vezethet. Az cookie alapú TempData szolgáltatóval kapcsolatos további információkért lásd CookieTempDataProvider.

TempData-szolgáltató kiválasztása

A TempData-szolgáltató kiválasztása több szempontot is magában foglal, például:

  • Az alkalmazás már használ munkamenet-állapotot? Ha igen, a TempData-szolgáltató munkamenet-állapotának használata nem jár további költségekkel az alkalmazás számára az adatok méretén túl.
  • Az alkalmazás csak takarékosan használja a TempData-t viszonylag kis mennyiségű, legfeljebb 500 bájtnyi adathoz? Ha igen, a cookie TempData-szolgáltató kis költséggel egészíti ki a TempData-t tartalmazó kérelmeket. Ha nem, a TempData munkamenet-állapot szolgáltató hasznos lehet, hogy elkerülje a nagy mennyiségű adat körbejárását az egyes kérések során, amíg a TempData felhasználásra kerül.
  • Az alkalmazás több kiszolgálón futó kiszolgálófarmban fut? Ha igen, nincs szükség további konfigurációra a cookie TempData-szolgáltató adatvédelemen kívüli használatához (lásd ASP.NET Alapvető adatvédelem áttekintése és kulcstároló-szolgáltatók).

A legtöbb webügyfél, például a webböngésző korlátozza az egyes cookie fájlok maximális méretét és a cookie-k teljes számát. A TempData-szolgáltató használatakor cookie ellenőrizze, hogy az alkalmazás nem lépi-e túl ezeket a korlátokat. Vegye figyelembe az adatok teljes méretét. Figyelembe kell venni a titkosítás és az cookie adattömb-készítés miatti méretnövekedést.

A TempData-szolgáltató konfigurálása

A cookie-based TempData szolgáltató alapértelmezés szerint engedélyezve van.

A munkamenet-alapú TempData-szolgáltató engedélyezéséhez használja a AddSessionStateTempDataProvider bővítménymetódust. Csak egyetlen AddSessionStateTempDataProvider hívásra van szükség.

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();
    });
}

Lekérdezési karakterláncok

Az új kérés lekérdezési sztringjének hozzáadásával korlátozott mennyiségű adat továbbítható az egyik kérelemből a másikba. Ez akkor hasznos, ha állandó módon rögzíti az állapotot, amely lehetővé teszi a beágyazott állapotra mutató hivatkozások megosztását e-mailben vagy közösségi hálózatokon keresztül. Mivel az URL-lekérdezési sztringek nyilvánosak, ne használjon lekérdezési sztringeket bizalmas adatokhoz.

A nem szándékos megosztás mellett, beleértve a lekérdezési sztringekben lévő adatokat is, az alkalmazás a helyek közötti kérelemhamisítási (CSRF-) támadásoknak is kiteheti az alkalmazást. Minden megőrzött munkamenet-állapotnak védelmet kell nyújtania a CSRF-támadások ellen. További információért lásd: Az ASP.NET Core alkalmazásban történő helyek közötti kéréshamisítás (XSRF/CSRF) elleni támadások megakadályozása.

Rejtett mezők

Az adatok menthetők rejtett űrlapmezőkbe, és a következő kérelemben közzétehetők. Ez gyakori a többoldalas űrlapokon. Mivel az ügyfél esetleg illetéktelenül módosíthatja az adatokat, az alkalmazásnak mindig újra kell értékelnie a rejtett mezőkben tárolt adatokat.

HttpContext.Items

A HttpContext.Items gyűjtemény egyetlen kérés feldolgozása során tárolja az adatokat. A rendszer a kérés feldolgozása után elveti a gyűjtemény tartalmát. A Items gyűjteményt gyakran arra használják, hogy lehetővé tegyék az összetevők vagy köztes szoftverek számára a kommunikációt, amikor a kérés során különböző időpontokban működnek, és nincs közvetlen mód a paraméterek átadására.

A következő példában a köztes szoftver hozzáadja isVerified a Items kollekcióhoz.

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"]}");
        });
    });
}

A csak egyetlen alkalmazásban használt köztes szoftver esetében a rögzített string kulcsok elfogadhatók. Az alkalmazások között megosztott köztes szoftvernek egyedi objektumkulcsokat kell használnia a kulcsütközések elkerülése érdekében. Az alábbi példa bemutatja, hogyan használható egy köztes szoftverosztályban definiált egyedi objektumkulcs:

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>();
    }
}

Más kód a köztes szoftverosztály által közzétett kulccsal érheti el a tárolt HttpContext.Items értéket:

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

Ennek a megközelítésnek az az előnye is, hogy megszünteti a kulcssztringek használatát a kódban.

Cache

A gyorsítótárazás hatékony módja az adatok tárolásának és lekérésének. Az alkalmazás szabályozhatja a gyorsítótárazott elemek élettartamát. További információért lásd: Válasz gyorsítótárazása az ASP.NET Core-ban.

A gyorsítótárazott adatok nincsenek hozzárendelve egy adott kéréshez, felhasználóhoz vagy munkamenethez. Ne gyorsítótárazza azokat a felhasználóspecifikus adatokat, amelyeket más felhasználói kérések kérhetnek le.

Az alkalmazásszintű adatok gyorsítótárazásához lásd: Gyorsítótár a memóriában ASP.NET Core-ban.

Gyakori hibák

Ha a munkamenet köztes szoftvere nem őriz meg egy munkamenetet:

  • A köztes szoftver naplózza a kivételt, és a kérés a szokásos módon folytatódik.
  • Ez kiszámíthatatlan viselkedéshez vezet.

A munkamenet köztes szoftvere nem tudja tárolni a munkamenetet, ha a háttértár nem érhető el. A felhasználó például munkamenet közben tárol egy bevásárlókocsit. A felhasználó hozzáad egy elemet a kosárhoz, de a véglegesítés sikertelen. Az alkalmazás nem tud a hibáról, ezért jelenti a felhasználónak, hogy az elemet hozzáadták a kosárhoz, ami nem igaz.

A hibák ellenőrzésének ajánlott módszere az, hogy hívja meg a await feature.Session.CommitAsync-t, amikor az alkalmazás befejezi a munkamenetbe való írást. CommitAsync kivételt eredményez, ha a háttértár nem érhető el. Ha CommitAsync nem sikerül, az alkalmazás feldolgozhatja a kivételt. LoadAsync azonos feltételek mellett hibát dob, amikor az adattár nem elérhető.

További erőforrások

ASP.NET Core üzemeltetése egy webfarmban