Freigeben über


ASP.NET core Blazor serverseitige Zustandsverwaltung

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.

In diesem Artikel werden allgemeine Ansätze für die Aufrechterhaltung der Daten (Status) eines Benutzers in serverseitigen Blazor Szenarien beschrieben.

Verwalten des Benutzerstatus

Serverseitiges Blazor ist ein zustandsbehaftetes App-Framework. In den meisten Fällen unterhält die App eine Verbindung mit dem Server. Der Benutzerzustand wird in einer Verbindung im Speicher des Servers gespeichert.

Beispiele für den in einer Verbindung gespeicherten Benutzerzustand sind:

  • Die Hierarchie der Komponenteninstanzen und deren neueste Renderausgabe in der gerenderten Benutzeroberfläche.
  • Die Werte der Felder und Eigenschaften in Komponenteninstanzen.
  • Daten, die in -Abhängigkeitsinjektion (DI)-Dienstinstanzen gespeichert sind, die auf die Verbindung beschränkt sind.

Der Benutzerzustand ist möglicherweise auch in JavaScript-Variablen im Arbeitsspeicher des Browsers enthalten, die über JavaScript-Interop-Aufrufe festgelegt werden.

Wenn die Netzwerkverbindung vorübergehend getrennt wird, versucht Blazor, den Benutzer nochmals mit der ursprünglichen Verbindung mit seinem ursprünglichen Zustand zu verbinden. Es ist jedoch nicht immer möglich, einen Benutzer noch mal mit der ursprünglichen Verbindung im Arbeitsspeicher des Servers zu verbinden:

  • Der Server kann eine getrennte Verbindung nicht dauerhaft beibehalten. Der Server muss eine getrennte Verbindung nach einem Timeout freigeben, oder wenn der Server nicht über genügend Arbeitsspeicher verfügt.
  • In Bereitstellungsumgebungen mit mehreren Servern und Lastenausgleich tritt bei einzelnen Servern möglicherweise ein Fehler auf, oder sie werden automatisch entfernt, wenn nicht mehr das gesamte Anforderungsvolumen verarbeitet werden muss. Die ursprünglichen Serververarbeitungsanforderungen für einen Benutzer sind möglicherweise nicht mehr verfügbar, wenn der Benutzer versucht, erneut eine Verbindung herzustellen.
  • Der Benutzer kann den Browser schließen und erneut öffnen oder die Seite neu laden, wodurch der im Arbeitsspeicher des Browsers enthaltene Zustand entfernt wird. So gehen beispielsweise JavaScript-Variablenwerte, die durch JavaScript-Interop-Aufrufe festgelegt wurden, verloren.

Wenn ein Benutzer nicht erneut mit dem ursprünglichen Schaltkreis verbunden werden kann, erhält der Benutzer einen neuen Schaltkreis mit neu initialisiertem Zustand. Dies entspricht dem Schließen und erneuten Öffnen einer Desktop-App.

Wann der Benutzerstatus beibehalten werden soll

Die Zustandspersistenz erfolgt nicht automatisch. Sie müssen bei der Entwicklung der App Schritte ausführen, um zustandsbehaftete Datenpersistenz zu implementieren.

Im Allgemeinen gilt: Die Beibehaltung des Zustands über Verbindungen hinweg erfolgt in Szenarien, in denen Benutzer aktiv Daten erstellen und nicht nur Daten lesen, die bereits vorhanden sind.

Die Datenpersistenz ist in der Regel nur für Zustände mit hohem Wert erforderlich, die von Benutzern mit großem Aufwand erstellt wurden. Der permanente Zustand spart Zeit oder Beihilfen in kommerziellen Tätigkeiten:

  • Webformulare mit mehreren Schritten: Es ist für den Benutzer zeitaufwändig, Daten für mehrere abgeschlossene Schritte eines mehrstufigen Webformulars wiederholt einzugeben, wenn der Zustand nicht mehr vorhanden ist. Der Benutzer verliert in diesem Szenario seinen Zustand, wenn er vom Formular weg navigiert und später zurückkehrt.
  • Warenkörbe: Kommerziell wichtige Komponenten einer App, die potenzielle Umsätze ermöglichen, können beibehalten werden. Ein Nutzer, der seinen Zustand verliert und damit seinen Einkaufswagen verliert, kann weniger Produkte oder Dienstleistungen erwerben, wenn er später auf die Website zurückkehrt.

Eine App kann nur den App-Zustand beibehalten. Benutzeroberflächen wie Komponenteninstanzen und deren Renderingstrukturen können nicht beibehalten werden. Komponenten und Renderingstrukturen sind in der Regel nicht serialisierbar. Um den Benutzeroberflächenzustand (z. B. von den erweiterten Knoten einer Strukturansicht) zu erhalten, muss die App über benutzerdefinierten Code verfügen, um das Verhalten des Benutzeroberflächenzustands als serialisierbaren App-Zustand modellieren zu können.

Schaltungszustandspersistenz

Während des serverseitigen Renderings kann s den Sitzungszustand (Schaltkreis) eines Benutzers beibehalten, Blazor Web Appwenn die Verbindung mit dem Server für einen längeren Zeitraum verloren geht oder proaktiv angehalten wird, solange keine Vollseitenaktualisierung ausgelöst wird. Auf diese Weise können Benutzer ihre Sitzung fortsetzen, ohne dass in den folgenden Szenarien nicht gespeicherte Arbeiten verloren gehen:

  • Browser-Tab-Drosselung
  • Benutzer mobiler Geräte, die Apps wechseln
  • Netzwerkunterbrechungen
  • Proaktives Ressourcenmanagement (Pause inaktiver Schaltkreise)
  • Erweiterte Navigation

Serverressourcen können freigegeben werden, wenn der Schaltkreiszustand beibehalten und später fortgesetzt werden kann:

  • Auch wenn die Verbindung getrennt ist, kann ein Schaltkreis weiterhin Arbeit ausführen und CPU, Arbeitsspeicher und andere Ressourcen verbrauchen. Der beibehaltene Zustand verbraucht nur einen festen Arbeitsspeicher, den der Entwickler steuert.
  • Der permanente Zustand stellt eine Teilmenge des von der App verbrauchten Speichers dar, sodass der Server nicht erforderlich ist, um die Komponenten der App und andere serverseitige Objekte nachzuverfolgen.

Der Status wird für zwei Szenarien gespeichert.

  • Komponentenstatus: Der Zustand, den Komponenten für das Interactive Server-Rendering verwenden, z. B. eine Liste von Elementen, die aus der Datenbank abgerufen wurden, oder ein Formular, das der Benutzer ausfüllt.
  • Bereichsbezogene Dienste: Zustand, der innerhalb eines serverseitigen Diensts gehalten wird, z. B. der aktuelle Benutzer.

Bedingungen:

  • Das Feature ist nur für das Interaktive Serverrendering wirksam.
  • Wenn der Benutzer die Seite (App) aktualisiert, geht der permanente Zustand verloren.
  • Der Zustand muss JSON serialisierbar sein. Zyklische Bezüge oder ORM-Entitäten könnten möglicherweise nicht korrekt serialisiert werden.
  • Verwenden Sie @key für Einzigartigkeit beim Rendern von Komponenten in einer Schleife, um Schlüsselkonflikte zu vermeiden.
  • Halten Sie nur den erforderlichen Zustand aufrecht. Das Speichern übermäßiger Daten kann sich auf die Leistung auswirken.
  • Kein automatischer Ruhezustand. Sie müssen die Statuspersistenz explizit aktivieren und konfigurieren.
  • Keine Garantie für die Wiederherstellung. Wenn die Zustandspersistenz fehlschlägt, fällt die App auf die Standard-Offline-Erfahrung zurück.

Zustandsspeicherung ist standardmäßig aktiviert, wenn AddInteractiveServerComponents auf AddRazorComponents in der Program Datei aufgerufen wird. MemoryCache ist die Standardspeicherimplementierung für einzelne App-Instanzen und speichert bis zu 1.000 permanente Schaltkreise für zwei Stunden, die konfigurierbar sind.

Verwenden Sie die folgenden Optionen, um die Standardwerte des Speicheranbieters zu ändern:

  • PersistedCircuitInMemoryMaxRetained ({CIRCUIT COUNT} Platzhalter): Die maximale Anzahl von Schaltungen, die aufbewahrt werden sollen. Der Standardwert ist 1.000 Schaltkreise. Verwenden Sie z. B. 2000, um den Zustand für bis zu 2.000 Schaltkreise beizubehalten.
  • PersistedCircuitInMemoryRetentionPeriod ({RETENTION PERIOD} Platzhalter): Der maximale Aufbewahrungszeitraum als TimeSpan. Der Standardwert ist zwei Stunden. Verwenden Sie TimeSpan.FromHours(3) z. B. für einen Aufbewahrungszeitraum von drei Stunden.
services.Configure<CircuitOptions>(options =>
{
    options.PersistedCircuitInMemoryMaxRetained = {CIRCUIT COUNT};
    options.PersistedCircuitInMemoryRetentionPeriod = {RETENTION PERIOD};
});

Das Speichern des Komponentenzustands über Systemkreise hinweg basiert auf der vorhandenen PersistentComponentState-API, die weiterhin den Zustand für vorab gerenderte Komponenten beibehält, die einen interaktiven Rendermodus verwenden. Weitere Informationen finden Sie unter ASP.NET core Blazor prerendered state persistenz.

[HINWEIS] Das Beibehalten des Komponentenzustands für die Vorrenderung funktioniert für jeden interaktiven Rendermodus, die Persistenz des Schaltkreiszustands funktioniert jedoch nur für den Interaktiven Server-Rendermodus .

Annotieren Sie Komponenteneigenschaften mit dem [PersistentState]-Attribut, um die Persistenz des Schaltkreiszustands zu ermöglichen. Im folgenden Beispiel werden auch die Elemente mit dem @key Direktiven-Attribut schlüsselt, um einen eindeutigen Bezeichner für jede Komponenteninstanz bereitzustellen:

@foreach (var item in Items)
{
    <ItemDisplay @key="@($"unique-prefix-{item.Id}")" Item="item" />
}

@code {
    [PersistentState]
    public List<Item> Items { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Items ??= await LoadItemsAsync();
    }
}

Um den Status für bereichsbezogene Dienste beizubehalten, kommentieren Sie die Diensteigenschaften mit dem [PersistentState] Attribut, fügen Sie den Dienst zur Dienstauflistung hinzu, und rufen Sie die RegisterPersistentService Erweiterungsmethode mit dem Dienst auf:

public class CustomUserService
{
    [PersistentState]
    public string UserData { get; set; }
}

services.AddScoped<CustomUserService>();

services.AddRazorComponents()
  .AddInteractiveServerComponents()
  .RegisterPersistentService<CustomUserService>(RenderMode.InteractiveAuto);

[HINWEIS] Im vorherigen Beispiel wird der Zustand UserData beibehalten, wenn der Dienst im Komponenten-Prerendering sowohl für interaktiven Server als auch für interaktives WebAssembly-Rendering verwendet wird, da RenderMode.InteractiveAuto auf RegisterPersistentService angegeben ist. Die Schaltungszustandspersistenz ist jedoch nur für den Interaktiven Server-Rendermodus verfügbar.

Um die Persistenz des verteilten Zustands (und als Standardstatuspersistenzmechanismus bei der Konfiguration) zu behandeln, weisen Sie der App eine HybridCache (API: HybridCache) zu, die ihren eigenen Persistenzzeitraum konfiguriert (PersistedCircuitDistributedRetentionPeriodstandardmäßig acht Stunden). HybridCache wird verwendet, da es einen einheitlichen Ansatz für verteilten Speicher bietet, der keine separaten Pakete für jeden Speicheranbieter erfordert.

Im folgenden Beispiel wird ein HybridCache mit dem Redis-Speicheranbieter implementiert.

services.AddHybridCache()
    .AddRedis("{CONNECTION STRING}");

services.AddRazorComponents()
    .AddInteractiveServerComponents();

Im vorherigen Beispiel stellt der {CONNECTION STRING} Platzhalter die Redis-Cacheverbindungszeichenfolge dar, die mithilfe eines sicheren Ansatzes bereitgestellt werden sollte, z. B. das Tool "Geheimer Manager " in der Development Umgebung oder Azure Key Vault mit azure Managed Identities für von Azure bereitgestellte Apps in jeder Umgebung.

Anhalten und Fortsetzen von Schaltkreisen

Anhalten und Fortsetzen von Schaltkreisen zum Implementieren von benutzerdefinierten Richtlinien, die die Skalierbarkeit einer App verbessern.

Beim Anhalten eines Schaltkreises werden Details zum Schaltkreis im clientseitigen Browserspeicher gespeichert und der Schaltkreis entfernt, der Serverressourcen freigibt. Durch die Fortsetzung des Schaltkreises wird ein neuer Schaltkreis eingerichtet und mithilfe des permanenten Zustands initialisiert.

Aus einem JavaScript-Ereignishandler:

  • Rufen Sie auf Blazor.pause , um einen Schaltkreis anzuhalten.
  • Rufen Sie auf Blazor.resume , um einen Schaltkreis fortzusetzen.

Im folgenden Beispiel wird davon ausgegangen, dass für eine nicht sichtbare App kein Schaltkreis erforderlich ist:

window.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    Blazor.pause();
  } else if (document.visibilityState === 'visible') {
    Blazor.resume();
  }
});

Persistentes verbindungsübergreifendes Speichern des Zustands

Im Allgemeinen gilt: Die Beibehaltung des Zustands über Verbindungen hinweg erfolgt in Szenarien, in denen Benutzer aktiv Daten erstellen und nicht nur Daten lesen, die bereits vorhanden sind.

Um den Zustand über Verbindungen hinweg beizubehalten, muss die App die Daten an einem anderen Speicherort als im Arbeitsspeicher des Servers persistent speichern. Die Zustandspersistenz erfolgt nicht automatisch. Sie müssen bei der Entwicklung der App Schritte ausführen, um zustandsbehaftete Datenpersistenz zu implementieren.

Die Datenpersistenz ist in der Regel nur für Zustände mit hohem Wert erforderlich, die von Benutzern mit großem Aufwand erstellt wurden. In den folgenden Beispielen werden durch die Beibehaltung des Zustands Zeit- oder Hilfsmitteleinsparungen in kommerziellen Aktivitäten erzielt:

  • Webformulare mit mehreren Schritten: Es ist für den Benutzer zeitaufwändig, Daten für mehrere abgeschlossene Schritte eines mehrstufigen Webformulars wiederholt einzugeben, wenn der Zustand nicht mehr vorhanden ist. Der Benutzer verliert in diesem Szenario seinen Zustand, wenn er vom Formular weg navigiert und später zurückkehrt.
  • Warenkörbe: Kommerziell wichtige Komponenten einer App, die potenzielle Umsätze ermöglichen, können beibehalten werden. Ein Benutzer, der seinen Zustand verliert und dessen Warenkorb dadurch gelöscht wird, kann weniger Produkte oder Dienste kaufen, wenn er zu einem späteren Zeitpunkt zur Website zurückkehrt.

Eine App kann nur den App-Zustand beibehalten. Benutzeroberflächen wie Komponenteninstanzen und deren Renderingstrukturen können nicht beibehalten werden. Komponenten und Renderingstrukturen sind in der Regel nicht serialisierbar. Um den Benutzeroberflächenzustand (z. B. von den erweiterten Knoten einer Strukturansicht) zu erhalten, muss die App über benutzerdefinierten Code verfügen, um das Verhalten des Benutzeroberflächenzustands als serialisierbaren App-Zustand modellieren zu können.

Serverseitige Speicherung

Für permanente Datenspeicherung, die mehrere Benutzer und Geräte umfasst, kann die App serverseitigen Speicher verwenden. Zu den Optionen gehören:

  • Blob Storage
  • Schlüssel-Wert-Speicher
  • Relationale Datenbank
  • Table Storage

Nachdem die Daten gespeichert wurden, wird der Zustand des Benutzers beibehalten und ist in jeder neuen Verbindung verfügbar.

Weitere Informationen zu den Azure-Datenspeicheroptionen finden Sie hier:

Browserspeicherung

Weitere Informationen finden Sie unter ASP.NET core Blazor state management using protected browser storage.

Weitere Ressourcen