Správa relací a stavu v ASP.NET Core
Od Rick Anderson, Kirka Larkina Diana LaRose
HTTP je bezstavový protokol. Ve výchozím nastavení jsou požadavky HTTP nezávislé zprávy, které neuchovávají hodnoty uživatele. Tento článek popisuje několik přístupů k zachování uživatelských dat mezi požadavky.
Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)
Správa stavu
Stav lze uložit pomocí několika přístupů. Jednotlivé metody jsou popsány dále v tomto tématu.
| Storage přístup | Storage mechanismus |
|---|---|
| Cookiepracují | HTTP cookie s. Může zahrnovat data uložená pomocí kódu aplikace na straně serveru. |
| Stav relace | HTTP cookie s a kód aplikace na straně serveru |
| TempData | HTTP cookie s nebo stav relace |
| Řetězce dotazů | Řetězce dotazů HTTP |
| Skrytá pole | Pole formuláře HTTP |
| HttpContext. Items | Kód aplikace na straně serveru |
| Cache | Kód aplikace na straně serveru |
Cookiepracují
Cookies ukládají data napříč požadavky. Vzhledem k tomu cookie , že s jsou odesílány s každou žádostí, jejich velikost musí být udržována minimálně. V ideálním případě by měl být pouze identifikátor uložen v cookie s daty uloženými aplikací. Většina prohlížečů omezuje cookie Velikost na 4096 bajtů. cookiePro každou doménu je k dispozici pouze omezený počet s.
Vzhledem cookie k tomu, že s podléhají manipulaci, musí je aplikace ověřit. Cookies můžou je odstranit uživatelé a vypršet na klientech. Nicméně cookie jsou všeobecně odolnější forma trvalosti dat na klientovi.
Cookies se často používají k přizpůsobení, kde je obsah přizpůsoben pro známého uživatele. Uživatel se ve většině případů identifikuje a není ověřený. cookieMůže ukládat jméno uživatele, název účtu nebo jedinečné ID uživatele, jako je například identifikátor GUID. cookieDá se použít pro přístup k individuálnímu nastavení uživatele, jako je například jeho preferovaná barva pozadí webu.
Přečtěte si Obecné nařízení o ochraně dat (GDPR) Evropské unie při vystavování cookie s a zabývat se zájmy ochrany osobních údajů. Další informace najdete v tématu podpora obecné nařízení o ochraně osobních údajů (GDPR) v ASP.NET Core.
Stav relace
stav relace je ASP.NET Core scénář pro ukládání uživatelských dat, když uživatel prochází webovou aplikaci. Stav relace používá úložiště udržované aplikací k zachování dat napříč požadavky klienta. Data relace jsou zálohovaná mezipamětí a považují se za data, která jsou považována za dočasné. Web by měl i nadále fungovat bez dat relace. Kritická data aplikace by měla být uložena v uživatelské databázi a v mezipaměti v rámci relace pouze jako optimalizace výkonu.
Relace není v aplikacích podporovaná, SignalR protože SignalR rozbočovač se může spustit nezávisle na kontextu http. K tomu může dojít například v případě, že je požadavek dlouhého cyklického dotazování otevřený centrem po dobu životnosti kontextu HTTP požadavku.
ASP.NET Core udržuje stav relace tím cookie , že poskytuje klientovi, který obsahuje ID relace. cookieID relace:
- Se do aplikace pošle s každým požadavkem.
- Používá aplikace k načtení dat relace.
Stav relace vykazuje následující chování:
- Relace cookie je specifická pro prohlížeč. Relace nejsou sdíleny mezi prohlížeči.
- Relace cookie s se odstraní, když se ukončí relace prohlížeče.
- Pokud cookie je přijata pro relaci s vypršenou platností, vytvoří se nová relace, která bude používat stejnou relaci cookie .
- Prázdné relace nejsou zachovány. Relace musí mít alespoň jednu nastavenou hodnotu pro zachování relace napříč požadavky. Pokud se relace nezachová, vygeneruje se pro každý nový požadavek nové ID relace.
- Aplikace po poslední žádosti zachovává relaci po určitou dobu. Aplikace buď nastaví časový limit relace, nebo použije výchozí hodnotu 20 minut. Stav relace je ideální pro ukládání uživatelských dat:
- To je specifické pro konkrétní relaci.
- Kde data nevyžadují trvalé úložiště napříč relacemi.
- Data relace se odstraní buď při ISession.Clear volání implementace, nebo po vypršení platnosti relace.
- Neexistuje žádný výchozí mechanismus pro informování kódu aplikace, že se zavřel klientský prohlížeč nebo když je relace cookie na klientovi Odstraněná nebo vypršela její platnost.
- Stav relace cookie s není ve výchozím nastavení označen jako základní. Stav relace není funkční, pokud návštěvník lokality nepovoluje sledování. Další informace naleznete v tématu Obecné nařízení o ochraně osobních údajů (GDPR) v ASP.NET Core.
Upozornění
Neukládejte citlivá data do stavu relace. Uživatel pravděpodobně neukončí prohlížeč a vymaže relaci cookie . Některé prohlížeče udržují platnou relaci cookie v oknech prohlížeče. Relace nemusí být omezena na jednoho uživatele. Další uživatel může pokračovat v procházení aplikace se stejnou relací cookie .
Poskytovatel mezipaměti v paměti ukládá data relace do paměti serveru, kde se aplikace nachází. Ve scénáři serverové farmy:
- Pomocí rychlých relací spojíte každou relaci s konkrétní instancí aplikace na samostatném serveru. Azure App Service využívá Směrování žádostí aplikace (ARR) k vykonání rychlých relací ve výchozím nastavení. Rychlé relace ale můžou ovlivnit škálovatelnost a zkomplikovat aktualizace webových aplikací. lepším řešením je použití distribuované mezipaměti Redis nebo SQL Server, která nevyžaduje relace v rychlém provozu. Další informace naleznete v tématu Distribuované ukládání do mezipaměti v ASP.NET Core.
- Relace cookie je šifrována prostřednictvím IDataProtector . Ochrana dat musí být správně nakonfigurovaná tak, aby na každém počítači přečetla relace cookie s. Další informace najdete v tématech ASP.NET Core Ochrana dat a poskytovatelé úložiště klíčů.
Konfigurovat stav relace
Balíček Microsoft. AspNetCore. Session :
- Je implicitně obsaženo v rozhraní.
- Poskytuje middleware pro správu stavu relace.
Chcete-li povolit middleware relace, Startup musí obsahovat:
- Libovolná IDistributedCache mezipaměť paměti.
IDistributedCacheImplementace se používá jako záložní úložiště pro relaci. Další informace naleznete v tématu Distribuované ukládání do mezipaměti v ASP.NET Core. - Volání AddSession v
ConfigureServices. - Volání UseSession v
Configure.
Následující kód ukazuje, jak nastavit zprostředkovatele relace v paměti s výchozí implementací v paměti 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();
});
}
}
Předchozí kód nastaví krátký časový limit pro zjednodušení testování.
Pořadí middlewaru je důležité. Volejte UseSession po UseRouting a před UseEndpoints . Viz Řazení middlewaru.
HttpContext.Session je k dispozici po nakonfigurování stavu relace.
HttpContext.Session nelze získat přístup před UseSession voláním.
Po zapisování aplikace do streamu odpovědí není možné vytvořit novou relaci s cookie novou relací. Výjimka se zaznamená do protokolu webového serveru a nezobrazí se v prohlížeči.
Asynchronní načtení stavu relace
Výchozí zprostředkovatel relace v ASP.NET Core načte záznamy relací ze základního backingového úložiště asynchronně pouze v případě, že je metoda explicitně volána před IDistributedCache ISession.LoadAsync TryGetValue metodami Set , nebo Remove . Pokud LoadAsync se nejprve nevolána, podkladový záznam relace se načte synchronně, což může ve velkém zvýšit výkon.
Pokud chcete, aby aplikace tento model vynucovat, zabalte implementace a s verzemi, které vyvolaly výjimku, pokud metoda není DistributedSessionStore DistributedSession LoadAsync volána před TryGetValue , nebo Set Remove . Zabalené verze zaregistrujte v kontejneru services.
Možnosti relace
Pokud chcete přepsat výchozí nastavení relace, použijte SessionOptions .
| Možnost | Popis |
|---|---|
| Cookie | Určuje nastavení použitá k vytvoření cookie . Name výchozí hodnota je SessionDefaults.CookieName ( .AspNetCore.Session ). Path výchozí hodnota je SessionDefaults.CookiePath ( / ). SameSite výchozí hodnota je SameSiteMode.Lax ( 1 ). HttpOnly výchozí hodnota je true . IsEssential výchozí hodnota je false . |
| IdleTimeout | Určuje, IdleTimeout jak dlouho může být relace nečinná, než se opouští její obsah. Každý přístup k relaci resetuje časový limit. Toto nastavení se vztahuje pouze na obsah relace, nikoli na cookie . Výchozí nastavení je 20 minut. |
| IOTimeout | Maximální doba, po kterou je možné načíst relaci z úložiště nebo ji potvrdit zpět do úložiště. Toto nastavení se může vztahovat pouze na asynchronní operace. Tento časový limit je možné zakázat pomocí InfiniteTimeSpan příkazu . Výchozí hodnota je 1 minuta. |
Relace používá ke cookie sledování a identifikaci požadavků z jednoho prohlížeče. Ve výchozím nastavení cookie má název a používá cestu .AspNetCore.Session / . Vzhledem k tomu, že výchozí hodnota nezadá doménu, není dostupná pro skript na straně klienta na stránce (protože výchozí hodnota cookie HttpOnly je true ).
Pokud chcete cookie přepsat výchozí nastavení relace, použijte 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();
}
Aplikace pomocí vlastnosti určuje, jak dlouho může být relace nečinná, než se její obsah v mezipaměti IdleTimeout serveru opouští. Tato vlastnost je nezávislá na vypršení cookie platnosti. Každý požadavek, který prochází middlewarem relace, resetuje časový limit.
Stav relace není zamykací. Pokud se současně pokusí upravit obsah relace dva požadavky, přepíše poslední požadavek první. Session se implementuje jako koherentní relace, což znamená, že se veškerý obsah ukládá společně. Když se dva požadavky snaží změnit různé hodnoty relace, poslední požadavek může přepsat změny relace provedené prvním požadavkem.
Nastavení a získání hodnot relace
Ke stavu relace se přistupuje Razor z třídy Pages nebo třídy PageModel MVC pomocí Controller HttpContext.Session . Tato vlastnost je ISession implementace.
Implementace ISession poskytuje několik rozšiřujících metod pro nastavení a načtení celočíselných a řetězcových hodnot. Metody rozšíření jsou v oboru Microsoft.AspNetCore.Http názvů .
ISession metody rozšíření:
- Get(ISession; String)
- GetInt32(ISession, String)
- GetString(ISession; String)
- SetInt32(ISession; String; Int32)
- SetString(ISession; String; String)
Následující příklad načte hodnotu relace pro klíč (v ukázkové IndexModel.SessionKeyName _Name aplikaci) na Razor stránce Stránky:
@page
@using Microsoft.AspNetCore.Http
@model IndexModel
...
Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)
Následující příklad ukazuje, jak nastavit a získat celé číslo a řetězec:
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);
Všechna data relace musí být serializován, aby bylo možné scénář distribuované mezipaměti, a to i při použití mezipaměti v paměti. Řetězcové a celočíselné serializátory jsou poskytované rozšiřujícími metodami ISession třídy . Komplexní typy musí být serializován uživatelem pomocí jiného mechanismu, například JSON.
K serializaci objektů použijte následující vzorový kód:
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);
}
}
Následující příklad ukazuje, jak nastavit a získat serializovatelný objekt s SessionExtensions třídou :
// Requires SessionExtensions from sample download.
if (HttpContext.Session.Get<DateTime>(SessionKeyTime) == default)
{
HttpContext.Session.Set<DateTime>(SessionKeyTime, currentTime);
}
TempData
ASP.NET Core zpřístupňuje Razor Pages TempData nebo Controller TempData . Tato vlastnost ukládá data, dokud se nenačtou v jiném požadavku. Metody Keep(String) a Peek(string) je možné použít k prozkoumání dat bez odstranění na konci požadavku. Zachovat označuje všechny položky ve slovníku pro uchování. TempData Je:
- Užitečné pro přesměrování, pokud jsou data nutná pro více než jeden požadavek.
- Implementovali
TempDataho zprostředkovatelé cookie pomocí stavu relace nebo .
Ukázky TempData
Představte si následující stránku, která vytvoří zákazníka:
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");
}
}
Na následující stránce se zobrazí TempData["Message"] :
@page
@model IndexModel
<h1>Peek Contacts</h1>
@{
if (TempData.Peek("Message") != null)
{
<h3>Message: @TempData.Peek("Message")</h3>
}
}
@*Content removed for brevity.*@
V předchozím kódu není na konci požadavku odstraněn, protože TempData["Message"] se používá Peek . Při aktualizaci stránky se zobrazí obsah TempData["Message"] souboru .
Následující kód je podobný předchozímu kódu, ale používá se k zachování Keep dat na konci požadavku:
@page
@model IndexModel
<h1>Contacts Keep</h1>
@{
if (TempData["Message"] != null)
{
<h3>Message: @TempData["Message"]</h3>
}
TempData.Keep("Message");
}
@*Content removed for brevity.*@
Při navigaci mezi stránkami IndexPeek a IndexKeep se příkaz TempData["Message"] odstraní.
Následující kód zobrazí , ale na konci požadavku TempData["Message"] TempData["Message"] se odstraní:
@page
@model IndexModel
<h1>Index no Keep or Peek</h1>
@{
if (TempData["Message"] != null)
{
<h3>Message: @TempData["Message"]</h3>
}
}
@*Content removed for brevity.*@
Zprostředkovatelé TempData
Zprostředkovatel cookie TempData založený na typu se ve výchozím nastavení používá k ukládání tempdata v cookie s.
Data cookie se zašifrují pomocí IDataProtector , zakódované pomocí Base64UrlTextEncoder a pak se zakódují do bloků dat. Maximální velikost je kvůli šifrování a blokům dat menší než cookie 4 096 bajtů. Data nejsou komprimovaná, protože komprese šifrovaných dat může vést k problémům se zabezpečením, jako jsou útoky CRIME a cookie BREACH. Další informace o poskytovateli cookie -based TempData najdete v tématu CookieTempDataProvider .
Volba zprostředkovatele TempData
Výběr poskytovatele TempData zahrnuje několik hledisek, například:
- Používá už aplikace stav relace? Pokud ano, poskytovatel tempData ve stavu relace nemá pro aplikaci žádné další náklady nad rámec velikosti dat.
- Používá aplikace tempData jen málo pro relativně malé objemy dat, až 500 bajtů? Pokud ano, poskytovatel TempData přidá ke každému požadavku, který přenáší cookie TempData, malé náklady. Pokud ne, může být zprostředkovatel tempData stavu relace výhodný, aby se zabránilo přecházování velkého množství dat v každém požadavku, dokud se nevyužívají data TempData.
- Běží aplikace v serverové farmě na více serverech? Pokud ano, není potřeba žádná další konfigurace pro použití zprostředkovatele TempData mimo ochranu dat cookie (viz a ASP.NET Core Ochrana dat Poskytovatelé úložiště klíčů).
Většina webových klientů, jako jsou webové prohlížeče, vynucuje omezení maximální velikosti každého z nich cookie a celkového počtu cookie s. Pokud používáte poskytovatele cookie TempData, ověřte, že aplikace nepřekročí tyto limity. Vezměte v úvahu celkovou velikost dat. Zohlednění cookie nárůstu velikosti z důvodu šifrování a bloků dat
Konfigurace zprostředkovatele TempData
Poskytovatel cookie TempData založený na systému je ve výchozím nastavení povolený.
Pokud chcete poskytovatele TempData založeného na relaci povolit, použijte AddSessionStateTempDataProvider metodu rozšíření . Vyžaduje se jenom jedno AddSessionStateTempDataProvider volání:
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();
});
}
Řetězce dotazů
Z jednoho požadavku do druhého je možné předat omezené množství dat tak, že je přidáte do řetězce dotazu nového požadavku. To je užitečné pro zachycení stavu trvalým způsobem, který umožňuje sdílet odkazy s vloženým stavem prostřednictvím e-mailu nebo sociálních sítí. Vzhledem k tomu, že řetězce dotazu URL jsou veřejné, nikdy nepoužívejte řetězce dotazů pro citlivá data.
Kromě nezamýšleného sdílení, včetně dat v řetězcích dotazů, může aplikace vystavit útokům prostřednictvím CSRF (mezi lokalitami) . Všechny zachované stavy relací musí chránit před CSRF útoky. Další informace naleznete v tématu Prevence útoků XSRF/CSRF (Cross-Site Request Forgery) v ASP.NET Core.
Skrytá pole
Data je možné uložit do skrytých polí formuláře a pak je odeslat zpět na další žádost. To je běžné ve vícestránkových formulářích. Vzhledem k tomu, že klient může potenciálně manipulovat s daty, aplikace musí vždy znovu ověřit data uložená ve skrytých polích.
HttpContext. Items
HttpContext.ItemsKolekce se používá k ukládání dat při zpracování jediné žádosti. Obsah kolekce se po zpracování žádosti zahodí. ItemsKolekce se často používá k tomu, aby komponenty nebo middleware komunikovaly, když pracují v různých časových okamžicích během žádosti a nemají přímý způsob předávání parametrů.
V následujícím příkladu middleware přidá isVerified do Items kolekce:
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"]}");
});
});
}
Pro middleware, které se používají jenom v jedné aplikaci, string jsou přijatelné i pevné klíče. Middleware sdílené mezi aplikacemi by měly používat jedinečné klíče objektů, aby se předešlo kolizi klíčů. Následující příklad ukazuje, jak použít jedinečný klíč objektu definovaný ve třídě middleware:
public class HttpContextItemsMiddleware
{
private readonly RequestDelegate _next;
public static readonly object HttpContextItemsMiddlewareKey = new Object();
public HttpContextItemsMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
httpContext.Items[HttpContextItemsMiddlewareKey] = "K-9";
await _next(httpContext);
}
}
public static class HttpContextItemsMiddlewareExtensions
{
public static IApplicationBuilder
UseHttpContextItemsMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<HttpContextItemsMiddleware>();
}
}
Další kód může přistupovat k hodnotě uložené v HttpContext.Items použití klíče vystaveného pomocí třídy middleware:
HttpContext.Items
.TryGetValue(HttpContextItemsMiddleware.HttpContextItemsMiddlewareKey,
out var middlewareSetValue);
SessionInfo_MiddlewareValue =
middlewareSetValue?.ToString() ?? "Middleware value not set!";
Tento přístup má také výhodu eliminace použití řetězců klíčů v kódu.
Mezipaměť
Ukládání do mezipaměti je účinný způsob, jak ukládat a načítat data. Aplikace může řídit dobu života položek v mezipaměti. Další informace naleznete v tématu Ukládání odpovědí do mezipaměti v ASP.NET Core.
Data uložená v mezipaměti nejsou přidružena ke konkrétnímu požadavku, uživateli nebo relaci. Neukládat do mezipaměti data specifická pro uživatele, která mohou být načtena jinými požadavky uživatele.
Chcete-li ukládat do mezipaměti data napříč aplikacemi, přečtěte si téma Ukládání do mezipaměti v ASP.NET Core .
Běžné chyby
"Nelze přeložit službu pro typ Microsoft. Extensions. Ukládání do mezipaměti. Distributed. IDistributedCache ' při pokusu o aktivaci ' Microsoft. AspNetCore. Session. DistributedSessionStore '.
To je obvykle způsobeno selháním konfigurace alespoň jedné
IDistributedCacheimplementace. Další informace naleznete v tématech Distribuované ukládání do mezipaměti v ASP.NET Core a Ukládání do mezipaměti v ASP.NET Core.
Pokud middleware relace nemůže uchovat relaci:
- Middleware zaznamená výjimku a požadavek bude normálně pokračovat.
- To vede k nepředvídatelnému chování.
Middleware relace může selhat při zachování relace, pokud není k dispozici záložní úložiště. Uživatel například ukládá v relaci nákupní košík. Uživatel přidá položku na košík, ale potvrzení se nezdařilo. Aplikace neví o selhání, takže oznamuje uživateli, že se položka přidala do svého košíku, což není pravda.
Doporučený postup pro kontrolu chyb je zavolat, await feature.Session.CommitAsync Jakmile se aplikace dokončí zápisem do relace. CommitAsync vyvolá výjimku, pokud není záložní úložiště k dispozici. CommitAsyncV případě chyby může aplikace zpracovat výjimku. LoadAsync Vyvolá se za stejných podmínek, když úložiště dat není k dispozici.
SignalR a stav relace
SignalR aplikace by neměly pro ukládání informací používat stav relace. SignalR aplikace se můžou ukládat na stav připojení v Context.Items centru.
Další zdroje informací
Od Rick Anderson, Steve Smith, Diana LaRosea Luke Latham
HTTP je bezstavový protokol. Bez provedení dalších kroků jsou požadavky HTTP nezávislé zprávy, které neuchovávají uživatelské hodnoty nebo stav aplikace. Tento článek popisuje několik přístupů k zachování uživatelských dat a stavu aplikace mezi požadavky.
Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)
Správa stavu
Stav lze uložit pomocí několika přístupů. Jednotlivé metody jsou popsány dále v tomto tématu.
| Storage přístup | Storage mechanismus |
|---|---|
| Cookiepracují | HTTP cookie s (může zahrnovat data uložená pomocí kódu aplikace na straně serveru) |
| Stav relace | HTTP cookie s a kód aplikace na straně serveru |
| TempData | HTTP cookie s nebo stav relace |
| Řetězce dotazů | Řetězce dotazů HTTP |
| Skrytá pole | Pole formuláře HTTP |
| HttpContext. Items | Kód aplikace na straně serveru |
| Cache | Kód aplikace na straně serveru |
| Injektáž závislostí | Kód aplikace na straně serveru |
Cookiepracují
Cookies ukládají data napříč požadavky. Vzhledem k tomu cookie , že s jsou odesílány s každou žádostí, jejich velikost musí být udržována minimálně. V ideálním případě by měl být pouze identifikátor uložen v cookie s daty uloženými aplikací. Většina prohlížečů omezuje cookie Velikost na 4096 bajtů. cookiePro každou doménu je k dispozici pouze omezený počet s.
Vzhledem cookie k tomu, že s podléhají manipulaci, musí je aplikace ověřit. Cookies můžou je odstranit uživatelé a vypršet na klientech. Nicméně cookie jsou všeobecně odolnější forma trvalosti dat na klientovi.
Cookies se často používají k přizpůsobení, kde je obsah přizpůsoben pro známého uživatele. Uživatel se ve většině případů identifikuje a není ověřený. cookieMůže ukládat jméno uživatele, název účtu nebo jedinečné ID uživatele (například identifikátor GUID). Pak můžete použít cookie pro přístup k individuálnímu nastavení uživatele, jako je například jeho preferovaná barva pozadí webu.
Nezapomeňte na obecné předpisy Evropské unie pro ochranu dat (GDPR) při vystavování cookie s a zabývat se zájmy ochrany osobních údajů. Další informace najdete v tématu podpora obecné nařízení o ochraně osobních údajů (GDPR) v ASP.NET Core.
Stav relace
stav relace je ASP.NET Core scénář pro ukládání uživatelských dat, když uživatel prochází webovou aplikaci. Stav relace používá úložiště udržované aplikací k zachování dat napříč požadavky klienta. Data relace jsou zálohovaná mezipamětí a považují se za nepřesná data — , která by měla lokalita dál fungovat bez dat relace. Kritická data aplikace by měla být uložena v uživatelské databázi a v mezipaměti v rámci relace pouze jako optimalizace výkonu.
Poznámka
Relace není v aplikacích podporovaná, SignalR protože SignalR rozbočovač se může spustit nezávisle na kontextu http. K tomu může dojít například v případě, že je požadavek dlouhého cyklického dotazování otevřený centrem po dobu životnosti kontextu HTTP požadavku.
ASP.NET Core udržuje stav relace tím cookie , že poskytuje klientovi, který obsahuje ID relace, která se pošle do aplikace s každým požadavkem. Aplikace používá ID relace k načtení dat relace.
Stav relace vykazuje následující chování:
- Vzhledem k tomu cookie , že relace je specifická pro prohlížeč, relace se v prohlížečích nesdílí.
- Relace cookie s se odstraní, když se ukončí relace prohlížeče.
- Pokud cookie je přijata pro relaci s vypršenou platností, vytvoří se nová relace, která bude používat stejnou relaci cookie .
- Prázdné relace nejsou zachované. — relace musí mít nastavenou aspoň jednu hodnotu, aby se relace mezi požadavky zachovala. Pokud se relace nezachová, vygeneruje se pro každý nový požadavek nové ID relace.
- Aplikace uchovává relaci po omezenou dobu po poslední žádosti. Aplikace buď nastaví časový limit relace, nebo použije výchozí hodnotu 20 minut. Stav relace je ideální pro ukládání uživatelských dat, která jsou specifická pro konkrétní relaci, ale kde data nevyžadují trvalé úložiště napříč relacemi.
- Data relace se odstraní buď při volání implementace, nebo při ISession.Clear vypršení platnosti relace.
- Neexistuje žádný výchozí mechanismus informování kódu aplikace o tom, že se klientský prohlížeč zavřel nebo že došlo k odstranění nebo vypršení cookie platnosti relace v klientovi.
- Šablona ASP.NET Core MVC a šablony stránek zahrnují podporu pro Obecné nařízení o ochraně osobních údajů Razor (GDPR). Stav relace není ve výchozím nastavení označený jako nezbytný, takže stav relace není funkční, pokud sledování cookie nepovolí návštěvník webu. Další informace naleznete v tématu Obecné nařízení o ochraně osobních údajů (GDPR) v ASP.NET Core.
Upozornění
Neukládejte citlivá data ve stavu relace. Uživatel nemusí prohlížeč zavřít a vymazat relaci cookie . Některé prohlížeče udržují platné relace cookie napříč okny prohlížeče. Relace nemusí být omezená na jednoho uživatele. Další uživatel může pokračovat v procházení aplikace se — stejnou relací cookie .
Poskytovatel mezipaměti v paměti ukládá data relace do paměti serveru, na kterém se aplikace nachází. Ve scénáři serverové farmy:
- Pomocí přichycené relace můžete každou relaci spojit s konkrétní instancí aplikace na individuálním serveru. Azure App Service používá směrování žádostí o aplikace (ARR) k vynucení přichycené relace ve výchozím nastavení. Přichycené relace ale mohou ovlivnit škálovatelnost a komplikovat aktualizace webových aplikací. Lepším přístupem je použít Redis nebo SQL Server mezipaměti, která nevyžaduje přichycené relace. Další informace naleznete v tématu Distribuované ukládání do mezipaměti v ASP.NET Core.
- Relace se cookie šifruje prostřednictvím IDataProtector . Ochrana dat musí být správně nakonfigurovaná tak, aby na každém počítači cookie četla relace s. Další informace najdete v tématu a ASP.NET Core Ochrana dat Poskytovatelé úložiště klíčů.
Konfigurace stavu relace
Balíček Microsoft.AspNetCore.Session, který je součástí Microsoft.AspNetCore.App metabalíček, poskytuje middleware pro správu stavu relace. Pokud chcete povolit middleware relace, Startup musí obsahovat:
- Kterákoli IDistributedCache z mezipamětí paměti. Implementace
IDistributedCachese používá jako zálohovací úložiště pro relaci. Další informace naleznete v tématu Distribuované ukládání do mezipaměti v ASP.NET Core. - Volání v AddSession
ConfigureServices. - Volání v UseSession
Configure.
Následující kód ukazuje, jak nastavit zprostředkovatele relace v paměti s výchozí implementací v paměti IDistributedCache :
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
// Make the session cookie essential
options.Cookie.IsEssential = true;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSession();
app.UseHttpContextItemsMiddleware();
app.UseMvc();
}
}
Pořadí middlewaru je důležité. V předchozím příkladu dojde k InvalidOperationException výjimce, UseSession když je vyvolána po UseMvc . Další informace najdete v tématu Řazení middlewaru.
HttpContext.Session je k dispozici po nakonfigurování stavu relace.
HttpContext.Session nelze získat přístup před UseSession voláním.
Po zapisování aplikace do streamu odpovědí není možné vytvořit novou relaci s cookie novou relací. Výjimka se zaznamená do protokolu webového serveru a nezobrazí se v prohlížeči.
Asynchronní načtení stavu relace
Výchozí zprostředkovatel relace v ASP.NET Core načte záznamy relací ze základního backingového úložiště asynchronně pouze v případě, že je metoda explicitně volána před IDistributedCache ISession.LoadAsync TryGetValue metodami Set , nebo Remove . Pokud LoadAsync se nejprve nevolána, podkladový záznam relace se načte synchronně, což může ve velkém zvýšit výkon.
Pokud chcete, aby aplikace tento model vynucovat, zabalte implementace a s verzemi, které vyvolaly výjimku, pokud metoda není DistributedSessionStore DistributedSession LoadAsync volána před TryGetValue , nebo Set Remove . Zabalené verze zaregistrujte v kontejneru services.
Možnosti relace
Pokud chcete přepsat výchozí nastavení relace, použijte SessionOptions .
| Možnost | Popis |
|---|---|
| Cookie | Určuje nastavení použitá k vytvoření cookie . Name výchozí hodnota je SessionDefaults.CookieName ( .AspNetCore.Session ). Path výchozí hodnota je SessionDefaults.CookiePath ( / ). SameSite výchozí hodnota je SameSiteMode.Lax ( 1 ). HttpOnly výchozí hodnota je true . IsEssential výchozí hodnota je false . |
| IdleTimeout | Určuje, IdleTimeout jak dlouho může být relace nečinná, než se opouští její obsah. Každý přístup k relaci resetuje časový limit. Toto nastavení se vztahuje pouze na obsah relace, nikoli na cookie . Výchozí nastavení je 20 minut. |
| IOTimeout | Maximální doba, po kterou je možné načíst relaci z úložiště nebo ji potvrdit zpět do úložiště. Toto nastavení se může vztahovat pouze na asynchronní operace. Tento časový limit je možné zakázat pomocí InfiniteTimeSpan příkazu . Výchozí hodnota je 1 minuta. |
Relace používá ke cookie sledování a identifikaci požadavků z jednoho prohlížeče. Ve výchozím nastavení cookie má název a používá cestu .AspNetCore.Session / . Vzhledem k tomu, že výchozí hodnota nezadá doménu, není dostupná pro skript na straně klienta na stránce (protože výchozí hodnota cookie HttpOnly je true ).
Pokud chcete cookie přepsat výchozí nastavení relace, použijte SessionOptions :
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedMemoryCache();
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSession(options =>
{
options.Cookie.Name = ".AdventureWorks.Session";
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.IsEssential = true;
});
}
Aplikace pomocí vlastnosti určuje, jak dlouho může být relace nečinná, než se její obsah v mezipaměti IdleTimeout serveru opouští. Tato vlastnost je nezávislá na vypršení cookie platnosti. Každý požadavek, který prochází middlewarem relace, resetuje časový limit.
Stav relace není zamykací. Pokud se současně pokusí upravit obsah relace dva požadavky, přepíše poslední požadavek první. Session se implementuje jako koherentní relace, což znamená, že se veškerý obsah ukládá společně. Když se dva požadavky snaží změnit různé hodnoty relace, poslední požadavek může přepsat změny relace provedené prvním požadavkem.
Nastavení a získání hodnot relace
Ke stavu relace se přistupuje Razor z třídy Pages nebo třídy PageModel MVC pomocí Controller HttpContext.Session . Tato vlastnost je ISession implementace.
Implementace ISession poskytuje několik rozšiřujících metod pro nastavení a načtení celočíselných a řetězcových hodnot. Metody rozšíření jsou v oboru názvů (přidejte příkaz pro získání přístupu k rozšiřujícím metodám), když projekt odkazuje na balíček Microsoft.AspNetCore.Http using Microsoft.AspNetCore.Http; Microsoft.AspNetCore.Http.Extensions. Oba balíčky jsou součástí Microsoft.AspNetCore.App metabalíku.
ISession metody rozšíření:
- Get(ISession; String)
- GetInt32(ISession, String)
- GetString(ISession; String)
- SetInt32(ISession; String; Int32)
- SetString(ISession; String; String)
Následující příklad načte hodnotu relace pro klíč (v ukázkové IndexModel.SessionKeyName _Name aplikaci) na Razor stránce Stránky:
@page
@using Microsoft.AspNetCore.Http
@model IndexModel
...
Name: @HttpContext.Session.GetString(IndexModel.SessionKeyName)
Následující příklad ukazuje, jak nastavit a získat celé číslo a řetězec:
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);
Všechna data relace musí být serializován, aby bylo možné scénář distribuované mezipaměti, a to i při použití mezipaměti v paměti. Řetězcové a celočíselné serializátory jsou poskytovány rozšiřujícími metodami ISession třídy ). Komplexní typy musí být serializován uživatelem pomocí jiného mechanismu, například JSON.
Přidejte následující metody rozšíření pro nastavení a získání serializovatelných objektů:
public static class SessionExtensions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) :
JsonConvert.DeserializeObject<T>(value);
}
}
Následující příklad ukazuje, jak nastavit a získat serializovatelný objekt pomocí rozšiřujících metod:
// Requires you add the Set and Get extension method mentioned in the topic.
if (HttpContext.Session.Get<DateTime>(SessionKeyTime) == default(DateTime))
{
HttpContext.Session.Set<DateTime>(SessionKeyTime, currentTime);
}
TempData
ASP.NET Core zpřístupňuje Razor Pages TempData nebo Controller TempData . Tato vlastnost ukládá data, dokud se nenačtou v jiném požadavku. Metody Keep(String) a Peek(string) je možné použít k prozkoumání dat bez odstranění na konci požadavku. Keep() označuje všechny položky ve slovníku pro uchování. TempData je zvláště užitečné pro přesměrování, pokud jsou data nutná pro více než jeden požadavek. TempData je implementovaná TempData zprostředkovateli cookie pomocí stavu relace nebo .
Ukázky TempData
Představte si následující stránku, která vytvoří zákazníka:
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");
}
}
Na následující stránce se zobrazí TempData["Message"] :
@page
@model IndexModel
<h1>Peek Contacts</h1>
@{
if (TempData.Peek("Message") != null)
{
<h3>Message: @TempData.Peek("Message")</h3>
}
}
@*Content removed for brevity.*@
V předchozím kódu není na konci požadavku odstraněn, protože TempData["Message"] se používá Peek . Při aktualizaci stránky se zobrazí TempData["Message"] .
Následující kód je podobný předchozímu kódu, ale používá se k zachování Keep dat na konci požadavku:
@page
@model IndexModel
<h1>Contacts Keep</h1>
@{
if (TempData["Message"] != null)
{
<h3>Message: @TempData["Message"]</h3>
}
TempData.Keep("Message");
}
@*Content removed for brevity.*@
Při navigaci mezi stránkami IndexPeek a IndexKeep se příkaz TempData["Message"] odstraní.
Následující kód zobrazí , ale na konci požadavku TempData["Message"] TempData["Message"] se odstraní:
@page
@model IndexModel
<h1>Index no Keep or Peek</h1>
@{
if (TempData["Message"] != null)
{
<h3>Message: @TempData["Message"]</h3>
}
}
@*Content removed for brevity.*@
Zprostředkovatelé TempData
Zprostředkovatel cookie TempData založený na typu se ve výchozím nastavení používá k ukládání tempdata v cookie s.
Data cookie se zašifrují pomocí IDataProtector , zakódované pomocí Base64UrlTextEncoder a pak se zakódují do bloků dat. Vzhledem k tomu, že hodnota je cookie blokovaná, limit jedné cookie velikosti ASP.NET Core 1.x neplatí. Data nejsou komprimovaná, protože komprese šifrovaných dat může vést k problémům se zabezpečením, jako jsou útoky CRIME a cookie BREACH. Další informace o poskytovateli cookie -based TempData najdete v tématu CookieTempDataProvider .
Volba zprostředkovatele TempData
Výběr poskytovatele TempData zahrnuje několik hledisek, například:
- Používá už aplikace stav relace? Pokud ano, nemá použití zprostředkovatele tempData stavu relace pro aplikaci žádné další náklady (kromě velikosti dat).
- Používá aplikace tempData jen málo pro relativně malé objemy dat (až 500 bajtů)? Pokud ano, poskytovatel TempData přidá ke každému požadavku, který přenáší cookie TempData, malé náklady. Pokud ne, může být zprostředkovatel tempData stavu relace výhodný, aby se zabránilo přecházování velkého množství dat v každém požadavku, dokud se nevyužívají data TempData.
- Běží aplikace v serverové farmě na více serverech? Pokud ano, není potřeba žádná další konfigurace pro použití zprostředkovatele TempData mimo ochranu dat cookie (viz a ASP.NET Core Ochrana dat Poskytovatelé úložiště klíčů).
Poznámka
Většina webových klientů (například webových prohlížečů) vynucuje omezení maximální velikosti každého z nich, celkového počtu cookie cookie s nebo obojího. Pokud používáte poskytovatele cookie TempData, ověřte, že aplikace nepřekročí tyto limity. Vezměte v úvahu celkovou velikost dat. Zohlednění cookie nárůstu velikosti z důvodu šifrování a bloků dat
Konfigurace zprostředkovatele TempData
Poskytovatel cookie TempData založený na systému je ve výchozím nastavení povolený.
Pokud chcete povolit zprostředkovatele TempData založeného na relaci, použijte AddSessionStateTempDataProvider metodu rozšíření:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddSessionStateTempDataProvider();
services.AddSession();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseMvc();
}
Pořadí middlewaru je důležité. V předchozím příkladu dojde k InvalidOperationException výjimce, UseSession když je vyvolána po UseMvc . Další informace najdete v tématu Řazení middlewaru.
Důležité
Pokud cílíte .NET Framework a používáte zprostředkovatele TempData založeného na relaci, přidejte do projektu balíček Microsoft.AspNetCore.Session.
Řetězce dotazů
Z jednoho požadavku do druhého je možné předat omezené množství dat tak, že je přidáte do řetězce dotazu nového požadavku. To je užitečné při trvalém zaznamenávání stavu, který umožňuje sdílení odkazů s vloženým stavem prostřednictvím e-mailu nebo sociálních sítí. Protože řetězce dotazů url jsou veřejné, nikdy nepoužívejte řetězce dotazů pro citlivá data.
Kromě nezamýšleného sdílení může zahrnutí dat do řetězců dotazů také vytvořit příležitosti pro útoky CSRF (Cross-Site Request Forgery), které mohou uživatele při ověřování oklamat k návštěvě škodlivých webů. Útočníci pak mohou z aplikace odcinout uživatelská data nebo jménem uživatele provádět škodlivé akce. Všechny zachované stavy aplikací nebo relací musí být chráněné před útoky CSRF. Další informace naleznete v tématu Prevence útoků XSRF/CSRF (Cross-Site Request Forgery) v ASP.NET Core.
Skrytá pole
Data je možné uložit do skrytých polí formuláře a odeslat zpět při dalším požadavku. To je běžné ve vícestránkovém formuláři. Vzhledem k tomu, že klient může potenciálně manipulovat s daty, musí aplikace vždy znovu ověřit data uložená ve skrytých polích.
HttpContext.Items
Kolekce HttpContext.Items se používá k ukládání dat při zpracování jednoho požadavku. Obsah kolekce se po zpracování požadavku zahodí. Kolekce se často používá k tomu, aby komponenty nebo middleware mohly komunikovat, když během požadavku pracují v různých bodech v čase a nemají přímý způsob předání Items parametrů.
V následujícím příkladu middleware isVerified přidá do kolekce Items .
app.Use(async (context, next) =>
{
// perform some verification
context.Items["isVerified"] = true;
await next.Invoke();
});
Později v kanálu má další middleware přístup k hodnotě isVerified :
app.Run(async (context) =>
{
await context.Response.WriteAsync($"Verified: {context.Items["isVerified"]}");
});
Pro middleware, který používá jenom jedna aplikace, string jsou klíče přijatelné. Middleware sdílený mezi instancemi aplikace by měl používat jedinečné klíče objektů, aby nedocházelo ke kolizím klíčů. Následující příklad ukazuje, jak použít jedinečný klíč objektu definovaný ve třídě middlewaru:
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 builder)
{
return builder.UseMiddleware<HttpContextItemsMiddleware>();
}
}
Jiný kód má přístup k hodnotě uložené v HttpContext.Items pomocí klíče vystavené třídou middlewaru:
HttpContext.Items
.TryGetValue(HttpContextItemsMiddleware.HttpContextItemsMiddlewareKey,
out var middlewareSetValue);
SessionInfo_MiddlewareValue =
middlewareSetValue?.ToString() ?? "Middleware value not set!";
Tento přístup má také výhodu v tom, že eliminuje použití klíčových řetězců v kódu.
Mezipaměť
Ukládání do mezipaměti je efektivní způsob, jak ukládat a načítat data. Aplikace může řídit dobu života položek uložených v mezipaměti.
Data uložená v mezipaměti nejsou přidružená ke konkrétnímu požadavku, uživateli ani relaci. Dávejte pozor, abyste neu mezipaměti ukládat data specifická pro uživatele, která mohou být načtena požadavky jiných uživatelů.
Další informace naleznete v tématu Ukládání odpovědí do mezipaměti v ASP.NET Core.
Injektáž závislostí
Pomocí injektáže závislostí z dostupných dat všem uživatelům:
Definujte službu obsahující data. Například třída s názvem
MyAppDataje definována:public class MyAppData { // Declare properties and methods }Přidejte třídu služby do
Startup.ConfigureServices:public void ConfigureServices(IServiceCollection services) { services.AddSingleton<MyAppData>(); }Využít třídu datové služby:
public class IndexModel : PageModel { public IndexModel(MyAppData myService) { // Do something with the service // Examples: Read data, store in a field or property } }
Běžné chyby
"Službu typu Microsoft.Extensions se nepodařilo přeložit. Ukládání do mezipaměti. Distributed.IDistributedCache při pokusu o aktivaci Microsoft.AspNetCore.Session.DistributedSessionStore
Příčinou je obvykle selhání konfigurace alespoň jedné
IDistributedCacheimplementace. Další informace naleznete v tématech Distribuované ukládání do mezipaměti v ASP.NET Core a Ukládání do mezipaměti v ASP.NET Core.V případě, že se middlewaru relace nepodaří zachovat relaci (například pokud není k dispozici zálohovací úložiště), middleware výjimku zahlásí a požadavek normálně pokračuje. To vede k nepředvídatelným chováním.
Uživatel například ukládá nákupní košík v relaci. Uživatel přidá položku do košíku, ale potvrzení se nezdaří. Aplikace o selhání neví, takže uživateli hlásí, že se položka přidala do košíku, což není pravda.
Doporučeným přístupem ke kontrole chyb je volání z kódu aplikace po zápisu aplikace
await feature.Session.CommitAsync();do relace.CommitAsyncvyvolá výjimku, pokud není k dispozici zálohovací úložiště. PokudCommitAsyncselže, aplikace může výjimku zpracovat.LoadAsyncvyvolá výjimku za stejných podmínek, kdy je úložiště dat nedostupné.
SignalR a stav relace
SignalR Aplikace by neměly k ukládání informací používat stav relace. SignalR Aplikace mohou ukládat stav připojení Context.Items v centru.