Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Door Rick Anderson, Kirk Larkin en Diana LaRose
HTTP is een staatloos protocol. HTTP-aanvragen zijn standaard onafhankelijke berichten die geen gebruikerswaarden behouden. In dit artikel worden verschillende benaderingen beschreven voor het behouden van gebruikersgegevens tussen aanvragen.
Zie voor Blazor richtlijnen voor statusbeheer, die de richtlijnen in dit artikel aanvullen of vervangen, de ASP.NET Core-overzicht van statusbeheerBlazor.
Toestandbeheer
Status kan worden opgeslagen met behulp van verschillende benaderingen. Elke benadering wordt verderop in dit artikel beschreven.
| Opslagbenadering | Opslagmechanisme | 
|---|---|
| Cookies | HTTP-cookies. Dit kunnen gegevens bevatten die zijn opgeslagen met behulp van app-code aan de serverzijde. | 
| Sessiestatus | HTTP-cookies en app-code aan de serverzijde | 
| TempData | HTTP-cookies of sessiestatus | 
| Queryreeksen | HTTP-queryreeksen | 
| Verborgen velden | HTTP-formuliervelden | 
| HttpContext.Items | App-code aan de serverzijde | 
| Cache | App-code aan de serverzijde | 
SignalR/Blazor Server en statusbeheer op basis van HTTP-context
              SignalR apps mogen geen sessiestatus en andere statusbeheermethoden gebruiken die afhankelijk zijn van een stabiele HTTP-context om informatie op te slaan. 
              SignalRapps kunnen de status per verbinding opslaan inContext.Items de hub. Zie voor meer informatie en alternatieve benaderingen voor statusbeheer bij Blazor Server-apps de overzicht van statusbeheer in ASP.NET Core Blazor en server-side statusbeheer in ASP.NET Core Blazor.
Cookies
Cookies slaan gegevens op over aanvragen. Omdat cookies bij elke aanvraag worden verzonden, moet de grootte ervan tot een minimum worden beperkt. In het ideale geval moet er alleen een identificator worden opgeslagen in een cookie, samen met de gegevens die door de app zijn opgeslagen. De meeste browsers beperken cookie de grootte tot 4096 bytes. Er zijn slechts een beperkt aantal cookies beschikbaar voor elk domein.
Omdat cookies onderhevig zijn aan manipulatie, moeten ze door de app worden gevalideerd. Cookies kunnen door gebruikers worden verwijderd en verlopen op clients. Cookies zijn echter over het algemeen de meest duurzame vorm van gegevenspersistentie op de client.
Cookies worden vaak gebruikt voor persoonlijke instellingen, waarbij inhoud wordt aangepast voor een bekende gebruiker. De gebruiker wordt in de meeste gevallen alleen geïdentificeerd en niet geverifieerd. De cookie kan de gebruikersnaam, accountnaam of unieke gebruikers-ID, zoals een GUID, opslaan. De cookie kan worden gebruikt voor toegang tot de persoonlijke instellingen van de gebruiker, zoals de achtergrondkleur van de website van hun voorkeur.
Zie de Algemene Verordening Gegevensbescherming van de Europese Unie (AVG) bij het uitgeven van cookies en het omgaan met privacyproblemen. Zie De ondersteuning voor algemene verordening gegevensbescherming (AVG) in ASP.NET Core voor meer informatie.
Sessiestatus
Sessiestatus is een ASP.NET Core-scenario voor het opslaan van gebruikersgegevens terwijl de gebruiker door een web-app bladert. De status van de sessie maakt gebruik van een opslag die door de app wordt onderhouden om gegevens te bewaren bij opeenvolgende verzoeken van een client. De sessiegegevens worden ondersteund door een cache en worden beschouwd als tijdelijke gegevens. De site moet blijven functioneren zonder de sessiegegevens. Kritieke toepassingsgegevens moeten worden opgeslagen in de gebruikersdatabase en enkel in de sessiecache worden opgeslagen als prestatieverbetering.
Sessie wordt niet ondersteund in SignalR apps omdat een SignalR hub onafhankelijk van een HTTP-context kan worden uitgevoerd. Dit kan bijvoorbeeld gebeuren wanneer een lange polling-aanvraag door een hub open wordt gehouden, waardoor deze langer duurt dan de levensduur van de HTTP-context van de aanvraag.
ASP.NET Core de sessiestatus behoudt door een cookie aan de client op te geven die een sessie-id bevat. De cookie sessie-id:
- Wordt met elke aanvraag naar de app verzonden.
 - Wordt door de app gebruikt om de sessiegegevens op te halen.
 
Sessiestatus vertoont het volgende gedrag:
- De sessie cookie is specifiek voor de browser. Sessies worden niet gedeeld tussen browsers.
 - Sessiecookies worden verwijderd wanneer de browsersessie afloopt.
 - Als er een cookie wordt ontvangen voor een verlopen sessie, wordt er een nieuwe sessie gemaakt die gebruikmaakt van dezelfde sessie cookie.
 - Lege sessies worden niet bewaard. De sessie moet ten minste één waarde hebben ingesteld om de sessie tussen verzoeken blijvend te maken. Wanneer een sessie niet wordt bewaard, wordt er een nieuwe sessie-id gegenereerd voor elke nieuwe aanvraag.
 - De app behoudt een sessie gedurende een beperkte periode na de laatste aanvraag. De app stelt de sessietime-out in of gebruikt de standaardwaarde van 20 minuten. Sessiestatus is ideaal voor het opslaan van gebruikersgegevens: 
- Dat is specifiek voor een bepaalde sessie.
 - Waar gegevens geen permanente opslag tussen sessies nodig hebben.
 
 - Sessiegegevens worden verwijderd wanneer de ISession.Clear implementatie wordt aangeroepen of wanneer de sessie verloopt.
 - Er is geen standaardmechanisme om app-code te informeren dat een clientbrowser is gesloten of wanneer de sessie cookie wordt verwijderd of verlopen op de client.
 - Cookies voor sessiestatus zijn niet standaard gemarkeerd als essentieel. Sessiestatus is niet functioneel tenzij het bijhouden is toegestaan door de bezoeker van de site. Zie De ondersteuning voor algemene verordening gegevensbescherming (AVG) in ASP.NET Core voor meer informatie.
 - Opmerking: Er is geen vervanging voor de sessiefunctie zonder cookies van het ASP.NET Framework omdat deze als onveilig wordt beschouwd en kan leiden tot sessiefixatieaanvallen.
 
Warning
Sla geen gevoelige gegevens op in sessiestatus. De gebruiker sluit de browser mogelijk niet en wist de sessie cookie. Sommige browsers onderhouden geldige sessiecookies in browservensters. Een sessie is mogelijk niet beperkt tot één gebruiker. De volgende gebruiker kan met dezelfde sessie cookiedoor de app blijven bladeren.
De cacheprovider in het geheugen slaat sessiegegevens op in het geheugen van de server waar de app zich bevindt. In een serverfarmscenario:
- Gebruik plaksessies om elke sessie te koppelen aan een specifiek app-exemplaar op een afzonderlijke server. Azure App Service maakt gebruik van Application Request Routing (ARR) om sticky sessions standaard af te dwingen. Plaksessies kunnen echter de schaalbaarheid beïnvloeden en webapp-updates bemoeilijken. Een betere benadering is het gebruik van een gedistribueerde Redis-, SQL Server- of Azure Postgres-cache, waarvoor geen plaksessies nodig zijn. Voor meer informatie, zie gedistribueerde caching in ASP.NET Core.
 - De sessie cookie wordt versleuteld via IDataProtector. Gegevensbescherming moet correct zijn geconfigureerd om sessiecookies op elke computer te lezen. Voor meer informatie, zie ASP.NET Core Data Protection Overzicht en sleutelopslagproviders.
 
Sessiestatus configureren
Middleware voor het beheren van de sessiestatus is opgenomen in het framework. Om de sessie-middleware in te schakelen, moet Program.cs het volgende bevatten:
- Een van de IDistributedCache geheugencaches. De 
IDistributedCacheimplementatie wordt gebruikt als opslagplaats voor de sessie. Voor meer informatie, zie gedistribueerde caching in ASP.NET Core. - Een aanroep naar AddSession
 - Een aanroep naar UseSession
 
De volgende code laat zien hoe u de in-memory sessieprovider instelt met een standaard in-memory implementatie van 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();
Met de voorgaande code wordt een korte time-out ingesteld om het testen te vereenvoudigen.
De volgorde van middleware is belangrijk.  Bel UseSession na UseRouting en voor MapRazorPages en MapDefaultControllerRoute . Zie Middleware bestellen.
HttpContext.Session is beschikbaar nadat de sessiestatus is geconfigureerd.
              HttpContext.Session kan niet worden geopend voordat UseSession is aangeroepen.
Een nieuwe sessie met een nieuwe sessie cookie kan niet worden gemaakt nadat de app is begonnen met schrijven naar de antwoordstroom. De uitzondering wordt vastgelegd in het webserverlogboek en wordt niet weergegeven in de browser.
Lade sessiestatus asynchroon
De standaardsessieprovider in ASP.NET Core laadt sessierecords van het onderliggende IDistributedCache backingarchief asynchroon alleen als de ISession.LoadAsync methode expliciet wordt aangeroepen vóór de TryGetValue, Setof Remove methoden. Als LoadAsync niet eerst wordt aangeroepen, wordt de onderliggende sessierecord op een gesynchroniseerde manier geladen, wat een prestatieverlies bij grotere schaal kan opleveren.
Als u wilt dat apps dit patroon afdwingen, verpakt u de DistributedSessionStore en DistributedSession implementaties met versies die een uitzondering genereren als de LoadAsync methode niet eerder TryGetValuewordt aangeroepen, Setof Remove. Registreer de verpakte versies in de servicescontainer.
Sessieopties
Als u de standaardinstellingen voor sessies wilt overschrijven, gebruikt u SessionOptions.
| Option | Description | 
|---|---|
| Cookie | Bepaalt de instellingen die worden gebruikt om de cookie. 
              Name wordt standaard ingesteld op SessionDefaults.CookieName (.AspNetCore.Session). 
              Path wordt standaard ingesteld op SessionDefaults.CookiePath (/). 
              SameSite wordt standaard ingesteld op SameSiteMode.Lax (1). 
              HttpOnly wordt standaard ingesteld op true. 
              IsEssential wordt standaard ingesteld op false. | 
| IdleTimeout | De IdleTimeout geeft aan hoe lang de sessie inactief kan zijn voordat de inhoud ervan wordt opgegeven. Elke sessietoegang stelt de time-out opnieuw in. Deze instelling is alleen van toepassing op de inhoud van de sessie, niet op de cookie. De standaardwaarde is 20 minuten. | 
| IOTimeout | De maximale hoeveelheid tijd die is toegestaan om een sessie uit de store te laden of om deze terug te zetten naar de store. Deze instelling is mogelijk alleen van toepassing op asynchrone bewerkingen. Deze time-out kan worden uitgeschakeld met behulp van InfiniteTimeSpan. De standaardwaarde is 1 minuut. | 
Sessie maakt gebruik van een cookie om aanvragen van één browser bij te houden en te identificeren. Standaard heeft deze cookie de naam .AspNetCore.Session en maakt gebruik van het pad /. Omdat de cookie standaardinstelling geen domein specificeert, wordt het niet beschikbaar gemaakt voor het script op de clientzijde van de pagina (omdat HttpOnly standaard true is).
Als u de standaardinstellingen voor sessies wilt overschrijven cookie , gebruikt u 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();
De app gebruikt de IdleTimeout eigenschap om te bepalen hoelang een sessie inactief kan zijn voordat de inhoud ervan in de cache van de server wordt verlaten. Deze eigenschap is onafhankelijk van de cookie vervaldatum. Elke aanvraag die via de Sessie-middleware wordt doorgegeven, stelt de time-out opnieuw in.
De sessiestatus is niet-vergrendelend. Als twee aanvragen tegelijkertijd proberen de inhoud van een sessie te wijzigen, overschrijft de laatste aanvraag de eerste. 
              Session wordt geïmplementeerd als een coherente sessie, wat betekent dat alle inhoud samen wordt opgeslagen. Wanneer twee aanvragen verschillende sessiewaarden willen wijzigen, kan de laatste aanvraag sessiewijzigingen negeren die door de eerste zijn aangebracht.
Sessiewaarden instellen en ophalen
Sessiestatus wordt geopend vanuit een Razor Pagina-klasse PageModel of MVC-klasse Controller met HttpContext.Session. Deze eigenschap is een ISession implementatie.
De ISession implementatie biedt verschillende uitbreidingsmethoden voor het instellen en ophalen van gehele getallen en tekenreekswaarden. De extensiemethoden bevinden zich in de Microsoft.AspNetCore.Http naamruimte.
              ISession extensiemethoden:
- Get(ISession, String)
 - GetInt32(ISession, String)
 - GetString(ISession, String)
 - SetInt32(ISession, Tekenreeks, Int32)
 - SetString(ISession, Snaar, String)
 
In het volgende voorbeeld wordt de sessiewaarde voor de IndexModel.SessionKeyName sleutel (_Name in voorbeeldtoepassing) op een Pages-pagina opgehaald.
@page
@using Microsoft.AspNetCore.Http
@model IndexModel
...
Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)
In het volgende voorbeeld bekijkt u hoe u een geheel getal en een tekenreeks instelt en opvraagt.
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);
    }
}
In de volgende markup worden de sessiewaarden op een Razor-pagina weergegeven.
@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>
Alle sessiegegevens moeten worden geserialiseerd om een scenario voor gedistribueerde cache mogelijk te maken, zelfs wanneer de cache in het geheugen wordt gebruikt. Serializers voor strings en integers worden geleverd door de uitbreidingsmethoden van ISession. Complexe typen moeten worden geserialiseerd door de gebruiker met behulp van een ander mechanisme, zoals JSON.
Gebruik de volgende voorbeeldcode om objecten te serialiseren:
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);
    }
}
In het volgende voorbeeld ziet u hoe u een serialiseerbaar object instelt en opkrijgt met de SessionExtensions klasse:
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
Het opslaan van een live-object in de sessie moet met voorzichtigheid worden gebruikt, omdat er veel problemen kunnen optreden met geserialiseerde objecten. Zie Sessies moeten objecten mogen opslaan (dotnet/aspnetcore #18159) voor meer informatie.
TempData
ASP.NET Core maakt de Razor Pagina's TempData of Controller TempData beschikbaar. Met deze eigenschap worden gegevens opgeslagen totdat deze in een andere aanvraag worden gelezen. De methoden Keep(String) en Peek(string) kunnen worden gebruikt om de gegevens te onderzoeken zonder te worden verwijderd aan het einde van de aanvraag. 
              Houd alle items in de woordenlijst gemarkeerd voor retentie. 
              TempData is:
- Handig voor omleiding wanneer gegevens vereist zijn voor meer dan één aanvraag.
 - Geïmplementeerd door 
TempDataproviders die cookies of sessiestatus gebruiken. 
TempData-voorbeelden
Houd rekening met de volgende pagina waarmee een klant wordt gemaakt:
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");
    }
}
Op de volgende pagina wordt het volgende weergegeven TempData["Message"]:
@page
@model IndexModel
<h1>Peek Contacts</h1>
@{
    if (TempData.Peek("Message") != null)
    {
        <h3>Message: @TempData.Peek("Message")</h3>
    }
}
@*Content removed for brevity.*@
Aan het einde van de aanvraag in de voorgaande markering wordt TempData["Message"]niet verwijderd omdat Peek wordt gebruikt. Als u de pagina ververst, wordt de inhoud van TempData["Message"] weergegeven.
De volgende markeringen zijn vergelijkbaar met de voorgaande code, maar worden gebruikt Keep om de gegevens aan het einde van de aanvraag te behouden:
@page
@model IndexModel
<h1>Contacts Keep</h1>
@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
    TempData.Keep("Message");
}
@*Content removed for brevity.*@
Navigeren tussen de pagina's IndexPeek en IndexKeep verwijdert TempData["Message"] niet.
De volgende code wordt weergegeven TempData["Message"], maar aan het einde van de aanvraag TempData["Message"] wordt verwijderd:
@page
@model IndexModel
<h1>Index no Keep or Peek</h1>
@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
}
@*Content removed for brevity.*@
TempData-providers
De cookie-gebaseerde TempDataprovider wordt standaard gebruikt om TempData op te slaan in cookies.
De cookie gegevens worden versleuteld met behulp van IDataProtector, gecodeerd met Base64UrlTextEncoderen vervolgens gesegmenteerd. De maximale cookie grootte is minder dan 4096 bytes vanwege versleuteling en segmentering. De cookie gegevens worden niet gecomprimeerd omdat het comprimeren van versleutelde gegevens kan leiden tot beveiligingsproblemen zoals de CRIME en BREACH aanvallen. Zie voor meer informatie over de op cookie gebaseerde TempData-provider CookieTempDataProvider.
Een TempData-provider kiezen
Het kiezen van een TempData-provider omvat verschillende overwegingen, zoals:
- Gebruikt de app al sessiestatus? Als dit het probleem is, heeft het gebruik van de TempData-provider voor sessiestatus geen extra kosten voor de app buiten de grootte van de gegevens.
 - Gebruikt de app TempData slechts spaarzaam voor relatief kleine hoeveelheden gegevens, maximaal 500 bytes? Zo ja, dan voegt de cookie TempData-provider een kleine kosten toe aan elke aanvraag die TempData bevat. Zo niet, dan kan de TempData-provider van de sessiestatus nuttig zijn om te voorkomen dat een grote hoeveelheid gegevens heen en weer wordt gestuurd bij elke aanvraag totdat de TempData wordt gebruikt.
 - Wordt de app uitgevoerd in een serverfarm op meerdere servers? Zo ja, dan is er geen aanvullende configuratie vereist voor het gebruik van de cookie TempData-provider buiten Data Protection. Voor meer informatie, zie ASP.NET Core Data Protection Overzicht en sleutelopslagproviders.
 
De meeste webclients, zoals webbrowsers, dwingen limieten af voor de maximale grootte van elk cookie en het totale aantal cookies. Wanneer u de cookie TempData-provider gebruikt, controleert u of de app deze limieten niet overschrijdt. Houd rekening met de totale grootte van de gegevens. Houd rekening met toenamen in cookie grootte vanwege versleuteling en segmentering.
De TempData-provider configureren
De cookie-gebaseerde TempData-provider is standaard ingeschakeld.
Als u de op sessies gebaseerde TempData-provider wilt inschakelen, gebruikt u de AddSessionStateTempDataProvider extensiemethode. Slechts één aanroep voor AddSessionStateTempDataProvider is vereist.
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();
Vraagreeksen
Een beperkte hoeveelheid gegevens kan van de ene aanvraag naar de andere worden doorgegeven door deze toe te voegen aan de querytekenreeks van de nieuwe aanvraag. Dit is handig voor het vastleggen van de status op een permanente manier waarmee koppelingen met de ingesloten status kunnen worden gedeeld via e-mail of sociale netwerken. Omdat URL-queryreeksen openbaar zijn, gebruikt u nooit queryreeksen voor gevoelige gegevens.
Naast onbedoeld delen, met inbegrip van gegevens in queryreeksen, kan de app worden blootgesteld aan CSRF-aanvallen (Cross-Site Request Forgery). Elke bewaarde sessiestatus moet bescherming bieden tegen CSRF-aanvallen. Zie Cross-Site Request Forgery -aanvallen (XSRF/CSRF) voorkomen in ASP.NET Corevoor meer informatie.
Verborgen velden
Gegevens kunnen worden opgeslagen in verborgen formuliervelden en worden teruggezet op de volgende aanvraag. Dit komt vaak voor in formulieren met meerdere pagina's. Omdat de client mogelijk manipulatie kan maken met de gegevens, moet de app altijd de gegevens die zijn opgeslagen in verborgen velden opnieuwvalideren.
HttpContext.Items
De HttpContext.Items verzameling wordt gebruikt om gegevens op te slaan tijdens het verwerken van één aanvraag. De inhoud van de verzameling wordt verwijderd nadat een aanvraag is verwerkt. De Items verzameling wordt vaak gebruikt om onderdelen of middleware toe te staan om te communiceren wanneer ze op verschillende tijdstippen tijdens een aanvraag werken en geen directe manier hebben om parameters door te geven.
In het volgende voorbeeld voegt middlewareisVerified toe aan de Items verzameling.
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();
Voor middleware die alleen in één app wordt gebruikt, is het onwaarschijnlijk dat het gebruik van een vaste string sleutel een sleutelconflict veroorzaakt. Om echter de mogelijkheid van een sleutelconflict helemaal te voorkomen, kan een object worden gebruikt als itemsleutel. Deze benadering is met name handig voor middleware die wordt gedeeld tussen apps en heeft ook het voordeel dat het gebruik van sleutelreeksen in de code wordt geëlimineerd. In het volgende voorbeeld ziet u hoe u een object sleutel gebruikt die is gedefinieerd in een middlewareklasse:
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>();
    }
}
Andere code heeft toegang tot de waarde die is opgeslagen in HttpContext.Items met behulp van de sleutel die door de middlewareklasse zichtbaar is gemaakt.
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
Caching is een efficiënte manier om gegevens op te slaan en op te halen. De app kan de levensduur van items in de cache beheren. Zie Antwoordcaching in ASP.NET Corevoor meer informatie.
Gegevens in de cache zijn niet gekoppeld aan een specifieke aanvraag, gebruiker of sessie. Sla gebruikersspecifieke gegevens die mogelijk worden opgehaald door andere gebruikersaanvragen niet in de cache op.
Zie Cache in het geheugen in ASP.NET Core als u toepassingsbrede gegevens in de cache wilt opslaan.
Sessiestatus controleren
              ISession.IsAvailable is bedoeld om te controleren op tijdelijke fouten. Aanroepen van IsAvailable voordat de sessie-middleware wordt uitgevoerd, veroorzaakt een InvalidOperationException.
Bibliotheken die de beschikbaarheid van sessies moeten testen, kunnen HttpContext.Features.Get<ISessionFeature>()?.Session != null gebruiken.
Veelvoorkomende fouten
Kan de service voor het type 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' niet oplossen bij het activeren van 'Microsoft.AspNetCore.Session.DistributedSessionStore'.
Dit wordt meestal veroorzaakt door het niet configureren van ten minste één
IDistributedCacheimplementatie. Zie Gedistribueerde cache in ASP.NET Core en Cache in het geheugen in ASP.NET Core voor meer informatie.
Als de sessie-middleware een sessie niet kan persistent maken:
- De middleware registreert de uitzondering en de aanvraag wordt normaal voortgezet.
 - Dit leidt tot onvoorspelbaar gedrag.
 
De sessie-middleware kan een sessie niet persistent maken als de back-upopslag niet beschikbaar is. Een gebruiker slaat bijvoorbeeld een winkelmandje op in een sessie. De gebruiker voegt een item toe aan de winkelwagen, maar de doorvoer mislukt. De app weet niet wat de fout is, zodat deze rapporteert aan de gebruiker dat het item is toegevoegd aan hun winkelwagen, wat niet waar is.
De aanbevolen methode om te controleren op fouten is door aan te roepen await feature.Session.CommitAsync wanneer de app klaar is met schrijven naar de sessie. 
              CommitAsync genereert een uitzondering als de backing store niet beschikbaar is. Als CommitAsync dit mislukt, kan de app de uitzondering verwerken. 
              LoadAsync genereert onder dezelfde omstandigheden wanneer het gegevensarchief niet beschikbaar is.
Aanvullende bronnen
Door Rick Anderson, Kirk Larkin en Diana LaRose
HTTP is een staatloos protocol. HTTP-aanvragen zijn standaard onafhankelijke berichten die geen gebruikerswaarden behouden. In dit artikel worden verschillende benaderingen beschreven voor het behouden van gebruikersgegevens tussen aanvragen.
Voorbeeldcode bekijken of downloaden (hoe download je)
Toestandbeheer
Status kan worden opgeslagen met behulp van verschillende benaderingen. Elke benadering wordt verderop in dit artikel beschreven.
| Opslagbenadering | Opslagmechanisme | 
|---|---|
| Cookies | HTTP-cookies. Dit kunnen gegevens bevatten die zijn opgeslagen met behulp van app-code aan de serverzijde. | 
| Sessiestatus | HTTP-cookies en app-code aan de serverzijde | 
| TempData | HTTP-cookies of sessiestatus | 
| Queryreeksen | HTTP-queryreeksen | 
| Verborgen velden | HTTP-formuliervelden | 
| HttpContext.Items | App-code aan de serverzijde | 
| Cache | App-code aan de serverzijde | 
SignalR/Blazor Server en statusbeheer op basis van HTTP-context
              SignalR apps mogen geen sessiestatus en andere statusbeheermethoden gebruiken die afhankelijk zijn van een stabiele HTTP-context om informatie op te slaan. 
              SignalRapps kunnen de status per verbinding opslaan inContext.Items de hub. Zie voor meer informatie en alternatieve benaderingen voor statusbeheer bij Blazor Server-apps de overzicht van statusbeheer in ASP.NET Core Blazor en server-side statusbeheer in ASP.NET Core Blazor.
Cookies
Cookies slaan gegevens op over aanvragen. Omdat cookies bij elke aanvraag worden verzonden, moet de grootte ervan tot een minimum worden beperkt. In het ideale geval moet er alleen een identificator worden opgeslagen in een cookie, samen met de gegevens die door de app zijn opgeslagen. De meeste browsers beperken cookie de grootte tot 4096 bytes. Er zijn slechts een beperkt aantal cookies beschikbaar voor elk domein.
Omdat cookies onderhevig zijn aan manipulatie, moeten ze door de app worden gevalideerd. Cookies kunnen door gebruikers worden verwijderd en verlopen op clients. Cookies zijn echter over het algemeen de meest duurzame vorm van gegevenspersistentie op de client.
Cookies worden vaak gebruikt voor persoonlijke instellingen, waarbij inhoud wordt aangepast voor een bekende gebruiker. De gebruiker wordt in de meeste gevallen alleen geïdentificeerd en niet geverifieerd. De cookie kan de gebruikersnaam, accountnaam of unieke gebruikers-ID, zoals een GUID, opslaan. De cookie kan worden gebruikt voor toegang tot de persoonlijke instellingen van de gebruiker, zoals de achtergrondkleur van de website van hun voorkeur.
Zie de Algemene Verordening Gegevensbescherming van de Europese Unie (AVG) bij het uitgeven van cookies en het omgaan met privacyproblemen. Zie De ondersteuning voor algemene verordening gegevensbescherming (AVG) in ASP.NET Core voor meer informatie.
Sessiestatus
Sessiestatus is een ASP.NET Core-scenario voor het opslaan van gebruikersgegevens terwijl de gebruiker door een web-app bladert. De status van de sessie maakt gebruik van een opslag die door de app wordt onderhouden om gegevens te bewaren bij opeenvolgende verzoeken van een client. De sessiegegevens worden ondersteund door een cache en worden beschouwd als tijdelijke gegevens. De site moet blijven functioneren zonder de sessiegegevens. Kritieke toepassingsgegevens moeten worden opgeslagen in de gebruikersdatabase en enkel in de sessiecache worden opgeslagen als prestatieverbetering.
Sessie wordt niet ondersteund in SignalR apps omdat een SignalR hub onafhankelijk van een HTTP-context kan worden uitgevoerd. Dit kan bijvoorbeeld gebeuren wanneer een lange polling-aanvraag door een hub open wordt gehouden, waardoor deze langer duurt dan de levensduur van de HTTP-context van de aanvraag.
ASP.NET Core de sessiestatus behoudt door een cookie aan de client op te geven die een sessie-id bevat. De cookie sessie-id:
- Wordt met elke aanvraag naar de app verzonden.
 - Wordt door de app gebruikt om de sessiegegevens op te halen.
 
Sessiestatus vertoont het volgende gedrag:
- De sessie cookie is specifiek voor de browser. Sessies worden niet gedeeld tussen browsers.
 - Sessiecookies worden verwijderd wanneer de browsersessie afloopt.
 - Als er een cookie wordt ontvangen voor een verlopen sessie, wordt er een nieuwe sessie gemaakt die gebruikmaakt van dezelfde sessie cookie.
 - Lege sessies worden niet bewaard. De sessie moet ten minste één waarde hebben ingesteld om de sessie tussen verzoeken blijvend te maken. Wanneer een sessie niet wordt bewaard, wordt er een nieuwe sessie-id gegenereerd voor elke nieuwe aanvraag.
 - De app behoudt een sessie gedurende een beperkte periode na de laatste aanvraag. De app stelt de sessietime-out in of gebruikt de standaardwaarde van 20 minuten. Sessiestatus is ideaal voor het opslaan van gebruikersgegevens: 
- Dat is specifiek voor een bepaalde sessie.
 - Waar gegevens geen permanente opslag tussen sessies nodig hebben.
 
 - Sessiegegevens worden verwijderd wanneer de ISession.Clear implementatie wordt aangeroepen of wanneer de sessie verloopt.
 - Er is geen standaardmechanisme om app-code te informeren dat een clientbrowser is gesloten of wanneer de sessie cookie wordt verwijderd of verlopen op de client.
 - Cookies voor sessiestatus zijn niet standaard gemarkeerd als essentieel. Sessiestatus is niet functioneel tenzij het bijhouden is toegestaan door de bezoeker van de site. Zie De ondersteuning voor algemene verordening gegevensbescherming (AVG) in ASP.NET Core voor meer informatie.
 
Warning
Sla geen gevoelige gegevens op in sessiestatus. De gebruiker sluit de browser mogelijk niet en wist de sessie cookie. Sommige browsers onderhouden geldige sessiecookies in browservensters. Een sessie is mogelijk niet beperkt tot één gebruiker. De volgende gebruiker kan met dezelfde sessie cookiedoor de app blijven bladeren.
De cacheprovider in het geheugen slaat sessiegegevens op in het geheugen van de server waar de app zich bevindt. In een serverfarmscenario:
- Gebruik plaksessies om elke sessie te koppelen aan een specifiek app-exemplaar op een afzonderlijke server. Azure App Service maakt gebruik van Application Request Routing (ARR) om sticky sessions standaard af te dwingen. Plaksessies kunnen echter de schaalbaarheid beïnvloeden en webapp-updates bemoeilijken. Een betere benadering is het gebruik van een gedistribueerde Redis-, SQL Server- of Azure Postgres-cache, waarvoor geen plaksessies nodig zijn. Voor meer informatie, zie gedistribueerde caching in ASP.NET Core.
 - De sessie cookie wordt versleuteld via IDataProtector. Gegevensbescherming moet correct zijn geconfigureerd om sessiecookies op elke computer te lezen. Voor meer informatie, zie ASP.NET Core Data Protection Overzicht en sleutelopslagproviders.
 
Sessiestatus configureren
Het pakket Microsoft.AspNetCore.Session :
- Wordt impliciet opgenomen in het framework.
 - Biedt middleware voor het beheren van de sessiestatus.
 
Om de sessie-middleware in te schakelen, moet Startup het volgende bevatten:
- Een van de IDistributedCache geheugencaches. De 
IDistributedCacheimplementatie wordt gebruikt als opslagplaats voor de sessie. Voor meer informatie, zie gedistribueerde caching in ASP.NET Core. - Een oproep naar AddSession binnen 
ConfigureServices. - Een oproep naar UseSession binnen 
Configure. 
De volgende code laat zien hoe u de in-memory sessieprovider instelt met een standaard in-memory implementatie van 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();
        });
    }
}
Met de voorgaande code wordt een korte time-out ingesteld om het testen te vereenvoudigen.
De volgorde van middleware is belangrijk.  Bel UseSession na UseRouting en voor UseEndpoints. Zie Middleware bestellen.
HttpContext.Session is beschikbaar nadat de sessiestatus is geconfigureerd.
              HttpContext.Session kan niet worden geopend voordat UseSession is aangeroepen.
Een nieuwe sessie met een nieuwe sessie cookie kan niet worden gemaakt nadat de app is begonnen met schrijven naar de antwoordstroom. De uitzondering wordt vastgelegd in het webserverlogboek en wordt niet weergegeven in de browser.
Lade sessiestatus asynchroon
De standaardsessieprovider in ASP.NET Core laadt sessierecords van het onderliggende IDistributedCache backingarchief asynchroon alleen als de ISession.LoadAsync methode expliciet wordt aangeroepen vóór de TryGetValue, Setof Remove methoden. Als LoadAsync niet eerst wordt aangeroepen, wordt de onderliggende sessierecord op een gesynchroniseerde manier geladen, wat een prestatieverlies bij grotere schaal kan opleveren.
Als u wilt dat apps dit patroon afdwingen, verpakt u de DistributedSessionStore en DistributedSession implementaties met versies die een uitzondering genereren als de LoadAsync methode niet eerder TryGetValuewordt aangeroepen, Setof Remove. Registreer de verpakte versies in de servicescontainer.
Sessieopties
Als u de standaardinstellingen voor sessies wilt overschrijven, gebruikt u SessionOptions.
| Option | Description | 
|---|---|
| Cookie | Bepaalt de instellingen die worden gebruikt om de cookie. 
              Name wordt standaard ingesteld op SessionDefaults.CookieName (.AspNetCore.Session). 
              Path wordt standaard ingesteld op SessionDefaults.CookiePath (/). 
              SameSite wordt standaard ingesteld op SameSiteMode.Lax (1). 
              HttpOnly wordt standaard ingesteld op true. 
              IsEssential wordt standaard ingesteld op false. | 
| IdleTimeout | De IdleTimeout geeft aan hoe lang de sessie inactief kan zijn voordat de inhoud ervan wordt opgegeven. Elke sessietoegang stelt de time-out opnieuw in. Deze instelling is alleen van toepassing op de inhoud van de sessie, niet op de cookie. De standaardwaarde is 20 minuten. | 
| IOTimeout | De maximale hoeveelheid tijd die is toegestaan om een sessie uit de store te laden of om deze terug te zetten naar de store. Deze instelling is mogelijk alleen van toepassing op asynchrone bewerkingen. Deze time-out kan worden uitgeschakeld met behulp van InfiniteTimeSpan. De standaardwaarde is 1 minuut. | 
Sessie maakt gebruik van een cookie om aanvragen van één browser bij te houden en te identificeren. Standaard heeft deze cookie de naam .AspNetCore.Session en maakt gebruik van het pad /. Omdat de cookie standaardinstelling geen domein specificeert, wordt het niet beschikbaar gemaakt voor het script op de clientzijde van de pagina (omdat HttpOnly standaard true is).
Als u de standaardinstellingen voor sessies wilt overschrijven cookie , gebruikt u 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();
}
De app gebruikt de IdleTimeout eigenschap om te bepalen hoelang een sessie inactief kan zijn voordat de inhoud ervan in de cache van de server wordt verlaten. Deze eigenschap is onafhankelijk van de cookie vervaldatum. Elke aanvraag die via de Sessie-middleware wordt doorgegeven, stelt de time-out opnieuw in.
De sessiestatus is niet-vergrendelend. Als twee aanvragen tegelijkertijd proberen de inhoud van een sessie te wijzigen, overschrijft de laatste aanvraag de eerste. 
              Session wordt geïmplementeerd als een coherente sessie, wat betekent dat alle inhoud samen wordt opgeslagen. Wanneer twee aanvragen verschillende sessiewaarden willen wijzigen, kan de laatste aanvraag sessiewijzigingen negeren die door de eerste zijn aangebracht.
Sessiewaarden instellen en ophalen
Sessiestatus wordt geopend vanuit een Razor Pagina-klasse PageModel of MVC-klasse Controller met HttpContext.Session. Deze eigenschap is een ISession implementatie.
De ISession implementatie biedt verschillende uitbreidingsmethoden voor het instellen en ophalen van gehele getallen en tekenreekswaarden. De extensiemethoden bevinden zich in de Microsoft.AspNetCore.Http naamruimte.
              ISession extensiemethoden:
- Get(ISession, String)
 - GetInt32(ISession, String)
 - GetString(ISession, String)
 - SetInt32(ISession, Tekenreeks, Int32)
 - SetString(ISession, Snaar, String)
 
In het volgende voorbeeld wordt de sessiewaarde voor de IndexModel.SessionKeyName sleutel (_Name in voorbeeldtoepassing) op een Pages-pagina opgehaald.
@page
@using Microsoft.AspNetCore.Http
@model IndexModel
...
Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)
In het volgende voorbeeld bekijkt u hoe u een geheel getal en een tekenreeks instelt en opvraagt.
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);
Alle sessiegegevens moeten worden geserialiseerd om een scenario voor gedistribueerde cache mogelijk te maken, zelfs wanneer de cache in het geheugen wordt gebruikt. Serializers voor strings en integers worden geleverd door de uitbreidingsmethoden van ISession. Complexe typen moeten worden geserialiseerd door de gebruiker met behulp van een ander mechanisme, zoals JSON.
Gebruik de volgende voorbeeldcode om objecten te serialiseren:
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);
    }
}
In het volgende voorbeeld ziet u hoe u een serialiseerbaar object instelt en opkrijgt met de SessionExtensions klasse:
// Requires SessionExtensions from sample download.
if (HttpContext.Session.Get<DateTime>(SessionKeyTime) == default)
{
    HttpContext.Session.Set<DateTime>(SessionKeyTime, currentTime);
}
TempData
ASP.NET Core maakt de Razor Pagina's TempData of Controller TempData beschikbaar. Met deze eigenschap worden gegevens opgeslagen totdat deze in een andere aanvraag worden gelezen. De methoden Keep(String) en Peek(string) kunnen worden gebruikt om de gegevens te onderzoeken zonder te worden verwijderd aan het einde van de aanvraag. 
              Houd alle items in de woordenlijst gemarkeerd voor retentie. 
              TempData is:
- Handig voor omleiding wanneer gegevens vereist zijn voor meer dan één aanvraag.
 - Geïmplementeerd door 
TempDataproviders die cookies of sessiestatus gebruiken. 
TempData-voorbeelden
Houd rekening met de volgende pagina waarmee een klant wordt gemaakt:
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");
    }
}
Op de volgende pagina wordt het volgende weergegeven TempData["Message"]:
@page
@model IndexModel
<h1>Peek Contacts</h1>
@{
    if (TempData.Peek("Message") != null)
    {
        <h3>Message: @TempData.Peek("Message")</h3>
    }
}
@*Content removed for brevity.*@
Aan het einde van de aanvraag in de voorgaande markering wordt TempData["Message"]niet verwijderd omdat Peek wordt gebruikt. Als u de pagina ververst, wordt de inhoud van TempData["Message"] weergegeven.
De volgende markeringen zijn vergelijkbaar met de voorgaande code, maar worden gebruikt Keep om de gegevens aan het einde van de aanvraag te behouden:
@page
@model IndexModel
<h1>Contacts Keep</h1>
@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
    TempData.Keep("Message");
}
@*Content removed for brevity.*@
Navigeren tussen de pagina's IndexPeek en IndexKeep verwijdert TempData["Message"] niet.
De volgende code wordt weergegeven TempData["Message"], maar aan het einde van de aanvraag TempData["Message"] wordt verwijderd:
@page
@model IndexModel
<h1>Index no Keep or Peek</h1>
@{
    if (TempData["Message"] != null)
    {
        <h3>Message: @TempData["Message"]</h3>
    }
}
@*Content removed for brevity.*@
TempData-providers
De cookie-gebaseerde TempDataprovider wordt standaard gebruikt om TempData op te slaan in cookies.
De cookie gegevens worden versleuteld met behulp van IDataProtector, gecodeerd met Base64UrlTextEncoderen vervolgens gesegmenteerd. De maximale cookie grootte is minder dan 4096 bytes vanwege versleuteling en segmentering. De cookie gegevens worden niet gecomprimeerd omdat het comprimeren van versleutelde gegevens kan leiden tot beveiligingsproblemen zoals de CRIME en BREACH aanvallen. Zie voor meer informatie over de op cookie gebaseerde TempData-provider CookieTempDataProvider.
Een TempData-provider kiezen
Het kiezen van een TempData-provider omvat verschillende overwegingen, zoals:
- Gebruikt de app al sessiestatus? Als dit het probleem is, heeft het gebruik van de TempData-provider voor sessiestatus geen extra kosten voor de app buiten de grootte van de gegevens.
 - Gebruikt de app TempData slechts spaarzaam voor relatief kleine hoeveelheden gegevens, maximaal 500 bytes? Zo ja, dan voegt de cookie TempData-provider een kleine kosten toe aan elke aanvraag die TempData bevat. Zo niet, dan kan de TempData-provider van de sessiestatus nuttig zijn om te voorkomen dat een grote hoeveelheid gegevens heen en weer wordt gestuurd bij elke aanvraag totdat de TempData wordt gebruikt.
 - Wordt de app uitgevoerd in een serverfarm op meerdere servers? Zo ja, dan is er geen aanvullende configuratie vereist voor het gebruik van de cookie TempData-provider buiten Data Protection (zie ASP.NET Core Data Protection Overview and Key Storage providers).
 
De meeste webclients, zoals webbrowsers, dwingen limieten af voor de maximale grootte van elk cookie en het totale aantal cookies. Wanneer u de cookie TempData-provider gebruikt, controleert u of de app deze limieten niet overschrijdt. Houd rekening met de totale grootte van de gegevens. Houd rekening met toenamen in cookie grootte vanwege versleuteling en segmentering.
De TempData-provider configureren
De cookie-gebaseerde TempData-provider is standaard ingeschakeld.
Als u de op sessies gebaseerde TempData-provider wilt inschakelen, gebruikt u de AddSessionStateTempDataProvider extensiemethode. Slechts één aanroep voor AddSessionStateTempDataProvider is vereist.
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();
    });
}
Vraagreeksen
Een beperkte hoeveelheid gegevens kan van de ene aanvraag naar de andere worden doorgegeven door deze toe te voegen aan de querytekenreeks van de nieuwe aanvraag. Dit is handig voor het vastleggen van de status op een permanente manier waarmee koppelingen met de ingesloten status kunnen worden gedeeld via e-mail of sociale netwerken. Omdat URL-queryreeksen openbaar zijn, gebruikt u nooit queryreeksen voor gevoelige gegevens.
Naast onbedoeld delen, met inbegrip van gegevens in queryreeksen, kan de app worden blootgesteld aan CSRF-aanvallen (Cross-Site Request Forgery). Elke bewaarde sessiestatus moet bescherming bieden tegen CSRF-aanvallen. Zie Cross-Site Request Forgery -aanvallen (XSRF/CSRF) voorkomen in ASP.NET Corevoor meer informatie.
Verborgen velden
Gegevens kunnen worden opgeslagen in verborgen formuliervelden en worden teruggezet op de volgende aanvraag. Dit komt vaak voor in formulieren met meerdere pagina's. Omdat de client mogelijk manipulatie kan maken met de gegevens, moet de app altijd de gegevens die zijn opgeslagen in verborgen velden opnieuwvalideren.
HttpContext.Items
De HttpContext.Items verzameling wordt gebruikt om gegevens op te slaan tijdens het verwerken van één aanvraag. De inhoud van de verzameling wordt verwijderd nadat een aanvraag is verwerkt. De Items verzameling wordt vaak gebruikt om onderdelen of middleware toe te staan om te communiceren wanneer ze op verschillende tijdstippen tijdens een aanvraag werken en geen directe manier hebben om parameters door te geven.
In het volgende voorbeeld voegt middlewareisVerified toe aan de Items verzameling.
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"]}");
        });
    });
}
Voor middleware die alleen in één app wordt gebruikt, zijn vaste string sleutels acceptabel. Middleware die wordt gedeeld tussen apps, moet gebruikmaken van unieke objectsleutels om belangrijke conflicten te voorkomen. In het volgende voorbeeld ziet u hoe u een unieke objectsleutel gebruikt die is gedefinieerd in een middlewareklasse:
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>();
    }
}
Andere code heeft toegang tot de waarde die is opgeslagen in HttpContext.Items met behulp van de sleutel die door de middlewareklasse zichtbaar is gemaakt.
HttpContext.Items
    .TryGetValue(HttpContextItemsMiddleware.HttpContextItemsMiddlewareKey, 
        out var middlewareSetValue);
SessionInfo_MiddlewareValue = 
    middlewareSetValue?.ToString() ?? "Middleware value not set!";
Deze aanpak heeft ook het voordeel van het elimineren van het gebruik van sleutelreeksen in de code.
Cache
Caching is een efficiënte manier om gegevens op te slaan en op te halen. De app kan de levensduur van items in de cache beheren. Zie Antwoordcaching in ASP.NET Corevoor meer informatie.
Gegevens in de cache zijn niet gekoppeld aan een specifieke aanvraag, gebruiker of sessie. Sla gebruikersspecifieke gegevens die mogelijk worden opgehaald door andere gebruikersaanvragen niet in de cache op.
Zie Cache in het geheugen in ASP.NET Core als u toepassingsbrede gegevens in de cache wilt opslaan.
Veelvoorkomende fouten
Kan de service voor het type 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' niet oplossen bij het activeren van 'Microsoft.AspNetCore.Session.DistributedSessionStore'.
Dit wordt meestal veroorzaakt door het niet configureren van ten minste één
IDistributedCacheimplementatie. Zie Gedistribueerde cache in ASP.NET Core en Cache in het geheugen in ASP.NET Core voor meer informatie.
Als de sessie-middleware een sessie niet kan persistent maken:
- De middleware registreert de uitzondering en de aanvraag wordt normaal voortgezet.
 - Dit leidt tot onvoorspelbaar gedrag.
 
De sessie-middleware kan een sessie niet persistent maken als de back-upopslag niet beschikbaar is. Een gebruiker slaat bijvoorbeeld een winkelmandje op in een sessie. De gebruiker voegt een item toe aan de winkelwagen, maar de doorvoer mislukt. De app weet niet wat de fout is, zodat deze rapporteert aan de gebruiker dat het item is toegevoegd aan hun winkelwagen, wat niet waar is.
De aanbevolen methode om te controleren op fouten is door aan te roepen await feature.Session.CommitAsync wanneer de app klaar is met schrijven naar de sessie. 
              CommitAsync genereert een uitzondering als de backing store niet beschikbaar is. Als CommitAsync dit mislukt, kan de app de uitzondering verwerken. 
              LoadAsync genereert onder dezelfde omstandigheden wanneer het gegevensarchief niet beschikbaar is.