Starten von ASP.NET Core Blazor

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

In diesem Artikel wird die Startkonfiguration von Blazor-Apps erläutert.

Allgemeine Leitfäden zur Konfiguration von ASP.NET Core-Apps für die serverseitige Entwicklung finden Sie unter Konfiguration in ASP.NET Core.

Startprozess und Konfiguration

Der Blazor-Startprozess erfolgt automatisch und asynchron über das Blazor-Skript (blazor.*.js), wobei der Platzhalter * folgendermaßen lautet:

  • web für eine Blazor-Web-App
  • server für eine Blazor Server-App
  • webassembly für eine Blazor WebAssembly-App

Der Blazor-Startprozess erfolgt automatisch und asynchron über das Blazor-Skript (blazor.*.js), wobei der Platzhalter * folgendermaßen lautet:

  • server für eine Blazor Server-App
  • webassembly für eine Blazor WebAssembly-App

Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

So starten Sie Blazor manuell:

Blazor-Web-App:

  • Fügen Sie dem Blazor-Tag <script> ein autostart="false"-Attribut und einen Wert hinzu.
  • Fügen Sie ein Skript, das Blazor.start() aufruft, nach dem Blazor-Tag <script> und innerhalb des schließenden </body>-Tags ein.
  • Fügen Sie Optionen für das statische serverseitige Rendering (statisches SSR) in die ssr-Eigenschaft ein.
  • Fügen Sie serverseitige Blazor- bzw. SignalR-Verbindungsoptionen in die circuit-Eigenschaft ein.
  • Fügen Sie clientseitige WebAssembly-Optionen in die webAssembly-Eigenschaft ein.
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ssr: {
      ...
    },
    circuit: {
      ...
    },
    webAssembly: {
      ...
    }
  });
  ...
</script>

Eigenständiges Blazor WebAssembly und Blazor Server:

  • Fügen Sie dem Blazor-Tag <script> ein autostart="false"-Attribut und einen Wert hinzu.
  • Fügen Sie ein Skript, das Blazor.start() aufruft, nach dem Blazor-Tag <script> und innerhalb des schließenden </body>-Tags ein.
  • Sie können zusätzliche Optionen im Parameter Blazor.start() angeben.
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ...
  });
  ...
</script>

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

JavaScript-Initialisierer

JavaScript-Initialisierer (JS) führen Logik vor und nach dem Laden einer Blazor-App aus. JS-Initialisierer sind in folgenden Szenarios nützlich:

  • Anpassen, wie eine Blazor-App geladen wird
  • Initialisieren von Bibliotheken vor dem Start von Blazor
  • Konfigurieren von Blazor-Einstellungen

JS-Initialisierer werden im Rahmen des Buildprozesses erkannt und automatisch importiert. Die Verwendung von JS-Initialisierern macht es oft überflüssig, Skriptfunktionen manuell in der App auszulösen , wenn Sie Razor-Klassenbibliotheken (RCLs) verwenden.

Fügen Sie zur Definition eines JS-Initialisierers dem Projekt ein JS-Modul mit dem Namen {NAME}.lib.module.js hinzu, wobei der Platzhalter {NAME} der Assemblyname, der Bibliotheksname oder der Paketbezeichner sein kann. Platzieren Sie die Datei im Webstammverzeichnis des Projekts, bei dem es sich in der Regel um den Ordner wwwroot handelt.

Für Blazor-Web-Apps:

  • beforeWebStart(options): Wird aufgerufen, bevor die Blazor-Web-App gestartet wird. Mit beforeWebStart können Sie zum Beispiel den Ladevorgang, den Protokollierungsgrad und andere Optionen anpassen. Empfängt die Blazor-Weboptionen (options).
  • afterWebStarted(blazor): Wird aufgerufen, nachdem alle beforeWebStart-Zusagen aufgelöst wurden. Beispielsweise kann afterWebStarted verwendet werden, um Blazor-Ereignislistener und benutzerdefinierte Ereignistypen zu registrieren. Die Blazor-Instanz wird als Argument (blazor) an afterWebStarted übergeben.
  • beforeServerStart(options, extensions): Wird aufgerufen, bevor die erste Serverlaufzeit gestartet wird. Empfängt SignalR-Leitungsstartoptionen (options) und alle Erweiterungen (extensions), die während der Veröffentlichung hinzugefügt werden.
  • afterServerStarted(blazor): Wird aufgerufen, nachdem die erste Laufzeit des interaktiven Servers gestartet wurde.
  • beforeWebAssemblyStart(options, extensions): Wird aufgerufen, bevor die interaktive WebAssembly-Laufzeit gestartet wird. Empfängt die Blazor-Optionen (options) und alle Erweiterungen (extensions), die während der Veröffentlichung hinzugefügt werden. Beispielsweise können Optionen die Verwendung eines benutzerdefinierten Startressourcen-Ladeprogramms angeben.
  • afterWebAssemblyStarted(blazor): Wird aufgerufen, nachdem die interaktive WebAssembly-Laufzeit gestartet wurde.

Hinweis

Legacy-JS-Initialisierer (beforeStart, afterStarted) werden in einer Blazor-Web-App nicht standardmäßig aufgerufen. Sie können die Legacy-Initialisierer mit der enableClassicInitializers-Option ausführen. Die Ausführung des Legacy-Initialisierers ist jedoch unvorhersehbar.

<script>
  Blazor.start({ enableClassicInitializers: true });
</script>

Für Blazor Server-, Blazor WebAssembly- und Blazor Hybrid-Apps:

  • beforeStart(options, extensions): Wird aufgerufen, bevor Blazor gestartet wird. Mit beforeStart können Sie zum Beispiel den Ladevorgang, den Protokollierungsgrad und andere für das Hostingmodell spezifische Optionen anpassen.
    • Client-seitig empfängt beforeStart die Blazor- Optionen (options) und alle Erweiterungen (extensions), die während der Veröffentlichung hinzugefügt werden. Beispielsweise können Optionen die Verwendung eines benutzerdefinierten Startressourcen-Ladeprogramms angeben.
    • Serverseitig empfängt beforeStartSignalR-Leitungsstartoptionen (options).
    • In BlazorWebView werden keine Optionen übergeben.
  • afterStarted(blazor): Wird aufgerufen, nachdem Blazor bereit ist, Aufrufe von JS zu empfangen. So wird afterStarted beispielsweise verwendet, um Bibliotheken zu initialisieren, indem JS-Interop-Aufrufe durchgeführt und benutzerdefinierte Elemente registriert werden. Die Blazor-Instanz wird als Argument (blazor) an afterStarted übergeben.

Zusätzliche .NET WebAssembly-Runtime-Rückrufe:

  • onRuntimeConfigLoaded(config): Wird aufgerufen, wenn die Startkonfiguration heruntergeladen wird. Ermöglicht der App, Parameter (Konfiguration) vor dem Start der Laufzeit zu ändern (der Parameter lautet MonoConfig von dotnet.d.ts):

    export function onRuntimeConfigLoaded(config) {
      // Sample: Enable startup diagnostic logging when the URL contains 
      // parameter debug=1
      const params = new URLSearchParams(location.search);
      if (params.get("debug") == "1") {
        config.diagnosticTracing = true;
      }
    }
    
  • onRuntimeReady({ getAssemblyExports, getConfig }): Wird aufgerufen, nachdem die .NET WebAssembly-Runtime gestartet wurde (der Parameter ist RuntimeAPI aus dotnet.d.ts):

    export function onRuntimeReady({ getAssemblyExports, getConfig }) {
      // Sample: After the runtime starts, but before Main method is called, 
      // call [JSExport]ed method.
      const config = getConfig();
      const exports = await getAssemblyExports(config.mainAssemblyName);
      exports.Sample.Greet();
    }
    

Beide Rückrufe können ein Promise zurückgeben, und die Zusage wird erwartet, bevor der Start fortgesetzt wird.

Für den Dateinamen gilt Folgendes:

  • Wenn die JS-Initialisierer als statisches Objekt im Projekt genutzt werden, verwenden Sie das Format {ASSEMBLY NAME}.lib.module.js. Hierbei steht der Platzhalter {ASSEMBLY NAME} für den Assemblynamen der App. Benennen Sie beispielsweise die Datei BlazorSample.lib.module.js für ein Projekt mit dem Assemblynamen BlazorSample. Platzieren Sie die Datei im Ordner wwwroot der App.
  • Wenn die JS-Initialisierer von einer RCL genutzt werden, verwenden Sie das Format {LIBRARY NAME/PACKAGE ID}.lib.module.js. Hierbei steht der Platzhalter {LIBRARY NAME/PACKAGE ID} für den Bibliotheksnamen oder den Paketbezeichner des Projekts. Benennen Sie beispielsweise die Datei RazorClassLibrary1.lib.module.js für eine RCL mit dem Paketbezeichner RazorClassLibrary1. Platzieren Sie die Datei im Ordner wwwroot der Bibliothek.

Für Blazor-Web-Apps:

Im folgenden Beispiel werden JS-Initialisierer veranschaulicht, die benutzerdefinierte Skripts vor und nach dem Start der Blazor-Web-App durch Anfügen an die <head> in beforeWebStart und afterWebStarted laden:

export function beforeWebStart() {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'beforeStartScripts.js');
  document.head.appendChild(customScript);
}

export function afterWebStarted() {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'afterStartedScripts.js');
  document.head.appendChild(customScript);
}

Das vorherige beforeWebStart-Beispiel stellt nur sicher, dass das benutzerdefinierte Skript geladen wird, bevor Blazor gestartet wird. Es garantiert nicht, dass erwartete Zusagen im Skript vollständig ausgeführt werden, bevor Blazor gestartet wird.

Für Blazor Server-, Blazor WebAssembly- und Blazor Hybrid-Apps:

Das folgende Beispiel zeigt JS-Initialisierer, die vor und nach dem Start von Blazor benutzerdefinierte Skripts laden, indem sie diese in beforeStart und afterStarted an <head> anfügen:

export function beforeStart(options, extensions) {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'beforeStartScripts.js');
  document.head.appendChild(customScript);
}

export function afterStarted(blazor) {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'afterStartedScripts.js');
  document.head.appendChild(customScript);
}

Das vorherige beforeStart-Beispiel stellt nur sicher, dass das benutzerdefinierte Skript geladen wird, bevor Blazor gestartet wird. Es garantiert nicht, dass erwartete Zusagen im Skript vollständig ausgeführt werden, bevor Blazor gestartet wird.

Hinweis

MVC- und Razor Pages-Apps laden JS-Initialisierer nicht automatisch. Jedoch kann der Entwicklercode ein Skript enthalten, das das Manifest der App abruft und das Laden der JS-Initialisierer auslöst.

Beispiele für JS-Initialisierer finden Sie in den folgenden Ressourcen:

Hinweis

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Sicherstellen, dass Bibliotheken in einer bestimmten Reihenfolge geladen werden

Fügen Sie benutzerdefinierte Skripts in beforeStart und afterStarted in der Reihenfolge an <head> an, in der sie geladen werden sollen.

Das folgende Beispiel lädt script1.js vor script2.js und script3.js vor script4.js:

export function beforeStart(options, extensions) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script1.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script2.js');
    document.head.appendChild(customScript2);
}

export function afterStarted(blazor) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script3.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script4.js');
    document.head.appendChild(customScript2);
}

Importieren zusätzlicher Module

Verwenden Sie import-Anweisungen auf oberster Ebene in der Datei des JS-Initialisierers, um zusätzliche Module zu importieren.

additionalModule.js:

export function logMessage() {
  console.log('logMessage is logging');
}

In der JS-Initialisiererdatei (.lib.module.js):

import { logMessage } from "/additionalModule.js";

export function beforeStart(options, extensions) {
  ...

  logMessage();
}

Importzuordnungen

Importzuordnungen werden von ASP.NET Core und Blazor unterstützt.

Initialisieren von Blazor, wenn das Dokument bereit ist

Das folgende Beispiel startet Blazor, wenn das Dokument bereit ist:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  document.addEventListener("DOMContentLoaded", function() {
    Blazor.start();
  });
</script>

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und dem Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Verketten mit dem Promise, der sich aus einem manuellen Start ergibt

Wenn Sie weitere Aufgaben wie etwa eine JS-Interop-Initialisierung ausführen möchten, verwenden Sie then für die Verkettung mit dem Promise, das sich aus dem manuellen Start der Blazor-App ergibt:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start().then(function () {
    ...
  });
</script>

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und dem Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Hinweis

Damit eine Bibliothek nach dem Start von Blazor automatisch weitere Aufgaben ausführt, verwenden Sie einen JavaScript-Initialisierer. Bei Verwendung eines JS-Initialisierers ist es nicht erforderlich, dass der Consumer der Bibliothek JS-Aufrufe mit dem manuellen Start von Blazor verkettet.

Laden clientseitiger Startressourcen

Wenn eine App im Browser geladen wird, lädt sie Startressourcen vom Server herunter:

  • JavaScript-Code zum Bootstrap der App
  • .NET-Runtime und Assemblys
  • Gebietsschemaspezifische Daten

Passen Sie an, wie diese Startressourcen mithilfe der loadBootResource-API geladen werden. Die loadBootResource-Funktion überschreibt den integrierten Lademechanismus für Startressourcen. Verwenden Sie loadBootResource für die folgenden Szenarien:

  • Laden Sie statische Ressourcen wie Zeitzonendaten oder dotnet.wasm aus einem CDN.
  • Komprimierte Assemblys über eine HTTP-Anforderung laden und auf dem Client für Hosts dekomprimieren, die das Abrufen komprimierter Inhalte vom Server nicht unterstützen.
  • Ressourcen per Alias an einen anderen Namen umleiten, indem jede fetch-Anforderung an einen neuen Namen umgeleitet wird.

Hinweis

Externe Quellen müssen die erforderlichen CORS-Header (Cross-Origin Resource Sharing) für Browser zurückgeben, um das ursprungsübergreifende Laden von Ressourcen zu ermöglichen. CDNs stellen in der Regel die erforderlichen Header standardmäßig zur Verfügung.

loadBootResource-Parameter sind in der folgenden Tabelle aufgeführt.

Parameter Beschreibung
type Der Typ der Ressource. Mögliche Typen sind: assembly, pdb, dotnetjs, dotnetwasm und timezonedata. Sie müssen nur für benutzerdefinierte Verhaltensmuster Typen angeben. Nicht mit loadBootResource angegebene Typen werden vom Framework entsprechend ihres Standardladeverhaltens geladen. Die dotnetjs-Startressource (dotnet.*.js) muss entweder null für das Standardladeverhalten oder einen URI für die Quelle der dotnetjs-Startressource zurückgeben.
name Der Name der Ressource.
defaultUri Der relative oder absolute URI der Ressource.
integrity Die Integritätszeichenfolge, die den erwarteten Inhalt in der Antwort darstellt.

Die loadBootResource-Funktion kann eine URI-Zeichenfolge zurückgeben, um den Ladevorgang zu überschreiben. Im Beispiel unten werden die folgenden Dateien aus bin/Release/{TARGET FRAMEWORK}/wwwroot/_framework von einem CDN unter https://cdn.example.com/blazorwebassembly/{VERSION}/ bereitgestellt:

  • dotnet.*.js
  • dotnet.wasm
  • Zeitzonendaten

Der Platzhalter {TARGET FRAMEWORK} ist der Zielframeworkmoniker (z. B. net7.0). Der Platzhalter {VERSION} ist die freigegebene Frameworkversion (z. B. 7.0.0).

Blazor-Web-App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
        switch (type) {
          case 'dotnetjs':
          case 'dotnetwasm':
          case 'timezonedata':
            return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
        }
      }
    }
  });
</script>

Blazor WebAssembly eigenständig:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
      switch (type) {
        case 'dotnetjs':
        case 'dotnetwasm':
        case 'timezonedata':
          return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
      }
    }
  });
</script>

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Um mehr als nur die URLs für Startressourcen anzupassen, kann die loadBootResource-Funktion fetch direkt aufrufen und das Ergebnis zurückgeben. Im folgenden Beispiel wird ein benutzerdefinierter HTTP-Header den ausgehenden Anforderungen hinzugefügt. Um das Standardverhalten bei der Integritätsprüfung beizubehalten, übergeben Sie den Parameter integrity in einem Header.

Blazor-Web-App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        if (type == 'dotnetjs') {
          return null;
        } else {
          return fetch(defaultUri, {
            cache: 'no-cache',
            integrity: integrity,
            headers: { 'Custom-Header': 'Custom Value' }
          });
        }
      }
    }
  });
</script>

Blazor WebAssembly eigenständig:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      if (type == 'dotnetjs') {
        return null;
      } else {
        return fetch(defaultUri, {
          cache: 'no-cache',
          integrity: integrity,
          headers: { 'Custom-Header': 'Custom Value' }
        });
      }
    }
  });
</script>

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Wenn die loadBootResource-Funktion null zurückgibt, verwendet Blazor das Standardladeverhalten für die Ressource. Der vorherige Code gibt beispielsweise null für die dotnetjs-Startressource (dotnet.*.js) zurück, da die dotnetjs-Startressource entweder null für das Standardladeverhalten oder einen URI für die Quelle der dotnetjs-Startressource zurückgeben muss.

Die loadBootResource-Funktion kann auch ein Response-Versprechen zurückgeben. Ein Beispiel finden Sie unter Hosten und Bereitstellen von Blazor WebAssembly in ASP.NET Core.

Weitere Informationen finden Sie unter ASP.NET Core Blazor WebAssembly .NET Runtime und App Bundle-Zwischenspeicherung.

Steuerelementheader in C#-Code

Hier erfahren Sie mehr über die Verwendung von Steuerelementheadern beim Starten in C#-Code mithilfe der folgenden Ansätze.

In den folgenden Beispielen wird eine Inhaltssicherheitsrichtlinie (Content Security Policy, CSP) über einen CSP-Header auf die App angewendet. Der Platzhalter {POLICY STRING} entspricht der CSP-Richtlinienzeichenfolge.

Serverseitige und vorab gerenderte clientseitige Szenarien

Verwenden SieASP.NET Core-Middleware, um die Sammlung „headers“ zu steuern.

Gehen Sie in der Program-Datei folgendermaßen vor:

In Startup.Configure von Startup.cs:

app.Use(async (context, next) =>
{
    context.Response.Headers.Append("Content-Security-Policy", "{POLICY STRING}");
    await next();
});

Im vorstehenden Beispiel wird Inline-Middleware verwendet. Sie können jedoch auch eine benutzerdefinierte Middlewareklasse erstellen und die Middleware mit einer Erweiterungsmethode in der Program-Datei aufrufen. Weitere Informationen finden Sie unter Schreiben von benutzerdefinierter ASP.NET Core Middleware.

Clientseitige Entwicklung ohne Vorabrendering

Übergeben Sie StaticFileOptions an MapFallbackToFile, um Antwortheader in der OnPrepareResponse-Stage anzugeben.

Gehen Sie in der serverseitigen Program-Datei folgendermaßen vor:

In Startup.Configure von Startup.cs:

var staticFileOptions = new StaticFileOptions
{
    OnPrepareResponse = context =>
    {
        context.Context.Response.Headers.Append("Content-Security-Policy", 
            "{POLICY STRING}");
    }
};

...

app.MapFallbackToFile("index.html", staticFileOptions);

Weitere Informationen zu CSPs finden Sie unter Erzwingen einer Inhaltssicherheitsrichtlinie für Blazor in ASP.NET Core.

Clientseitiges Laden von Statusindikatoren

Eine Ladestatusanzeige zeigt den Ladefortschritt der App für Benutzer*innen an. Dies weist darauf hin, dass die App normal geladen wird und dass Benutzer*innen warten sollten, bis der Ladevorgang abgeschlossen ist.

Ladestatus der Blazor-Web-App

Die in Blazor WebAssembly-Apps verwendete Ladestatusanzeige ist in einer App, die auf der Grundlage der Blazor-Web-App-Projektvorlage erstellt wurde, nicht vorhanden. In der Regel ist eine Ladestatusanzeige für interaktive WebAssembly-Komponenten nicht wünschenswert, da Blazor-Web-Apps clientseitige Komponenten auf dem Server vorab rendern, um die anfänglichen Ladezeiten zu verkürzen. Bei Situationen im gemischten Rendermodus muss das Framework oder der Entwicklercode auch darauf achten, die folgenden Probleme zu vermeiden:

  • Anzeigen mehrerer Indikatoren für den Ladevorgang auf derselben gerenderten Seite
  • Versehentliches Verwerfen der vorab gerenderten Inhalte beim Laden der WebAssembly-Runtime

In einem zukünftigen Release von .NET kann eine Framework-basierte Ladestatusanzeige bereitgestellt werden. In der Zwischenzeit können Sie einer Blazor-Web-App eine benutzerdefinierte Ladestatusanzeige hinzufügen.

Erstellen Sie eine LoadingProgress-Komponente in der .Client-App, die OperatingSystem.IsBrowser aufruft:

  • Bei false wird während des Downloads des Blazor-Pakets und vor der Aktivierung der Blazor-Runtime auf dem Client eine Ladestatusanzeige angezeigt.
  • Bei true wird der Inhalt der angeforderten Komponente gerendert.

Die folgende Demo verwendet die Ladestatusanzeige in Apps, die mithilfe der Blazor WebAssembly-Vorlage erstellt wurden, einschließlich einer Änderung der von der Vorlage bereitgestellten Formatvorlagen. Die Formatvorlagen werden von der HeadContent-Komponente in den <head>-Inhalt der App geladen. Weitere Informationen finden Sie unter Steuern des Inhalts von „head“ in Blazor-Apps in ASP.NET Core.

LoadingProgress.razor:

@if (!OperatingSystem.IsBrowser())
{
    <HeadContent>
        <style>
            .loading-progress {
                position: relative;
                display: block;
                width: 8rem;
                height: 8rem;
                margin: 20vh auto 1rem auto;
            }

                .loading-progress circle {
                    fill: none;
                    stroke: #e0e0e0;
                    stroke-width: 0.6rem;
                    transform-origin: 50% 50%;
                    transform: rotate(-90deg);
                }

                    .loading-progress circle:last-child {
                        stroke: #1b6ec2;
                        stroke-dasharray: 
                            calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 
                            500%;
                        transition: stroke-dasharray 0.05s ease-in-out;
                    }

            .loading-progress-text {
                position: relative;
                text-align: center;
                font-weight: bold;
                top: -90px;
            }

                .loading-progress-text:after {
                    content: var(--blazor-load-percentage-text, "Loading");
                }

            code {
                color: #c02d76;
            }
        </style>
    </HeadContent>
    <svg class="loading-progress">
        <circle r="40%" cx="50%" cy="50%" />
        <circle r="40%" cx="50%" cy="50%" />
    </svg>
    <div class="loading-progress-text"></div>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}

Umschließen Sie in einer Komponente, die interaktives WebAssembly-Rendering verwendet, das Razor-Markup der Komponente mit der LoadingProgress-Komponente. Das folgende Beispiel veranschaulicht den Ansatz mit der Counter-Komponente einer App, die aus der Blazor-Web-App-Projektvorlage erstellt wurde.

Pages/Counter.razor:

@page "/counter"
@rendermode InteractiveWebAssembly

<PageTitle>Counter</PageTitle>

<LoadingProgress>
    <h1>Counter</h1>

    <p role="status">Current count: @currentCount</p>

    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</LoadingProgress>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Ladestatus der Blazor WebAssembly-App

Die Projektvorlage enthält skalierbare Vektorgrafiken (Scalable Vector Graphics, SVG) und Textindikatoren, die den Ladefortschritt der App anzeigen.

Die Statusindikatoren werden mit HTML und CSS mithilfe von zwei benutzerdefinierten CSS-Eigenschaften (Variablen) implementiert, die von Blazor bereitgestellt werden:

  • --blazor-load-percentage: Der Prozentsatz der geladenen App-Dateien.
  • --blazor-load-percentage-text: Der Prozentsatz der geladenen App-Dateien auf die nächste ganze Zahl gerundet.

Mithilfe der vorherigen CSS-Variablen können Sie benutzerdefinierte Statusindikatoren erstellen, die dem Stil Ihrer App entsprechen.

Im folgenden Beispiel:

  • resourcesLoaded ist eine sofortige Angabe der Anzahl der Ressourcen, die beim Starten der App geladen wurden.
  • totalResources ist die Gesamtanzahl der zu ladenden Ressourcen.
const percentage = resourcesLoaded / totalResources * 100;
document.documentElement.style.setProperty(
  '--blazor-load-percentage', `${percentage}%`);
document.documentElement.style.setProperty(
  '--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`);

Der standardmäßige runde Fortschrittsindikator wird in HTML in der Datei wwwroot/index.html implementiert:

<div id="app">
    <svg class="loading-progress">
        <circle r="40%" cx="50%" cy="50%" />
        <circle r="40%" cx="50%" cy="50%" />
    </svg>
    <div class="loading-progress-text"></div>
</div>

Weitere Informationen zum -Projektvorlagenmarkup und zum Stil der Standardstatusindikatoren finden Sie in der ASP.NET Core-Referenz:

Hinweis

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Anstatt den standardmäßigen runden Fortschrittsindikator zu verwenden, zeigt das folgende Beispiel, wie ein linearer Fortschrittsindikator implementiert wird.

Fügen Sie die folgenden Formatvorlagen in wwwroot/css/app.css hinzu:

.linear-progress {
    background: silver;
    width: 50vw;
    margin: 20% auto;
    height: 1rem;
    border-radius: 10rem;
    overflow: hidden;
    position: relative;
}

.linear-progress:after {
    content: '';
    position: absolute;
    inset: 0;
    background: blue;
    scale: var(--blazor-load-percentage, 0%) 100%;
    transform-origin: left top;
    transition: scale ease-out 0.5s;
}

Eine CSS-Variable (var(...)) wird dazu verwendet, den Wert von --blazor-load-percentage an die scale-Eigenschaft eines blauen Pseudoelements zu übergeben, das den Ladefortschritt der Dateien der App angibt. Wenn die App geladen wird, wird --blazor-load-percentage automatisch aktualisiert, wodurch sich die visuelle Darstellung des Statusindikators dynamisch ändert.

Entfernen Sie in wwwroot/index.html den runden SVG-Standardindikator in <div id="app">...</div>, und ersetzen Sie ihn durch das folgende Markup:

<div class="linear-progress"></div>

Konfigurieren der .NET-WebAssembly-Runtime

In erweiterten Programmierszenarios wird die configureRuntime-Funktion mit dem dotnet-Runtimehost-Generator verwendet, um die .NET WebAssembly-Runtime zu konfigurieren. Beispielsweise legt dotnet.withEnvironmentVariable eine Umgebungsvariable fest, die:

  • die .NET WebAssembly-Runtime konfiguriert
  • das Verhalten einer C-Bibliothek ändert

Die configureRuntime-Funktion kann auch verwendet werden, um die Integration mit einem Browserprofiler zu ermöglichen.

In den folgenden Beispielen, die eine Umgebungsvariable festlegen, gilt Folgendes:

  • Der Platzhalter {BLAZOR SCRIPT} entspricht dem Blazor-Skriptpfad und -Dateinamen. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.
  • Der Platzhalter {NAME} ist der Name der Umgebungsvariable.
  • Der Platzhalter {VALUE} ist der Wert der Umgebungsvariable.

Blazor-Web-App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      configureRuntime: dotnet => {
        dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
      }
    }
  });
</script>

Blazor WebAssembly eigenständig:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureRuntime: dotnet => {
      dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
    }
  });
</script>

Hinweis

Auf die .NET-Runtimeinstanz kann mithilfe der Blazor WebAssembly-Runtime-API (Blazor.runtime) zugegriffen werden. Die Buildkonfiguration der App kann z. B. mit Blazor.runtime.runtimeBuildInfo.buildConfiguration abgerufen werden.

Weitere Informationen zur .NET WebAssembly-Runtimekonfiguration finden Sie in der TypeScript-Definitionsdatei (dotnet.d.ts) der Runtime im dotnet/runtime-GitHub-Repository.

Hinweis

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Deaktivieren der erweiterten Navigation und Formularverarbeitung

Dieser Abschnitt gilt für Blazor-Web-Apps.

Um die erweiterte Navigation und Formularverarbeitung zu deaktivieren, legen Sie disableDomPreservation für Blazor.start auf true fest.

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    ssr: { disableDomPreservation: true }
  });
</script>

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Zusätzliche Ressourcen