Implementatie-indeling voor ASP.NET Core gehoste Blazor WebAssembly-apps
In dit artikel wordt uitgelegd hoe u gehoste Blazor WebAssembly-implementaties inschakelt in omgevingen die het downloaden en uitvoeren van DLL-bestanden (Dynamic Link Library) blokkeren.
Notitie
Deze richtlijnen hebben betrekking op omgevingen die verhinderen dat clients DLL's downloaden en uitvoeren. In .NET 8 of hoger gebruikt Blazor de bestandsindeling webcil om dit probleem op te lossen. Zie Host en implementeer ASP.NET Core Blazor WebAssemblyvoor meer informatie. Bundeling met meerdere onderdelen met behulp van het experimentele NuGet-pakket dat in dit artikel wordt beschreven, wordt niet ondersteund voor Blazor apps in .NET 8 of hoger. U kunt de richtlijnen in dit artikel gebruiken om uw eigen NuGet-pakket met meerdere onderdelen te maken voor .NET 8 of hoger.
Blazor WebAssembly apps vereisen DLL's (dynamisch koppelbare bibliotheken) om te functioneren, maar sommige omgevingen voorkomen dat clients DLL's downloaden en uitvoeren. In een subset van deze omgevingen is het wijzigen van de bestandsnaamextensie van DLL-bestanden (.dll
) voldoende is om beveiligingsbeperkingen te omzeilen, maar beveiligingsproducten kunnen vaak de inhoud scannen van bestanden die het netwerk passeren en DLL-bestanden blokkeren of in quarantaine plaatsen. In dit artikel wordt één benadering beschreven voor het inschakelen van Blazor WebAssembly apps in deze omgevingen, waarbij een bundelbestand met meerdere onderdelen wordt gemaakt op basis van de DLL's van de app, zodat de DLL's samen kunnen worden gedownload om beveiligingsbeperkingen te omzeilen.
Een gehoste Blazor WebAssembly-app kan de gepubliceerde bestanden en pakketten van app-DLL's aanpassen met behulp van de volgende functies:
- JavaScript-initialisaties waarmee het opstartproces van Blazor kan worden aangepast.
- MSBuild-extensibiliteit om de lijst met gepubliceerde bestanden te transformeren en Blazor Publiceerextensieste definiëren. Blazor Publicatie-extensies zijn bestanden die tijdens het publicatieproces zijn gedefinieerd en die een alternatieve weergave bieden voor de set bestanden die nodig zijn om een gepubliceerde Blazor WebAssembly-app uit te voeren. In dit artikel wordt een Blazor Publish Extension gemaakt die een bundel met meerdere onderdelen produceert met alle DLL's van de app die zijn verpakt in één bestand, zodat de DLL's samen kunnen worden gedownload.
De aanpak die in dit artikel wordt gedemonstreerd, fungeert als uitgangspunt voor ontwikkelaars om hun eigen strategieën en aangepaste laadprocessen te bedenken.
Waarschuwing
Elke aanpak die wordt genomen om een beveiligingsbeperking te omzeilen, moet zorgvuldig worden overwogen voor de gevolgen van de beveiliging. We raden u aan het onderwerp verder te verkennen met de netwerkbeveiligingsprofessionals van uw organisatie voordat u de aanpak in dit artikel gaat gebruiken. Alternatieven om rekening mee te houden zijn:
- Schakel beveiligingsapparaten en beveiligingssoftware in zodat netwerkclients de exacte bestanden kunnen downloaden en gebruiken die vereist zijn voor een Blazor WebAssembly-app.
- Schakel over van het Blazor WebAssembly hostingmodel naar het Blazor Server hostingmodel, dat alle C#-code van de app op de server onderhoudt en geen DLL's naar clients hoeft te downloaden. Blazor Server biedt ook het voordeel van het privé houden van C#-code zonder dat het gebruik van web-API-apps voor C#-codeprivacy met Blazor WebAssembly-apps is vereist.
Experimenteel NuGet-pakket en voorbeeld-app
De benadering die in dit artikel wordt beschreven, wordt gebruikt door het experimenteleMicrosoft.AspNetCore.Components.WebAssembly.MultipartBundle
-pakket (NuGet.org) voor apps die gericht zijn op .NET 6 of hoger. Het pakket bevat MSBuild-doelen voor het aanpassen van de Blazor-uitvoer en een JavaScript-initializer- voor het gebruik van een aangepast opstartresourcelaadprogramma, die allemaal verderop in dit artikel worden beschreven.
experimentele code (bevat de bron van de NuGet-pakketreferentie en CustomPackagedApp
voorbeeld-app)
Waarschuwing
Experimentele en preview-functies worden geboden voor het verzamelen van feedback en worden niet ondersteund voor productiegebruik.
Verderop in dit artikel geeft de sectie "Het aanpassen van het laadproces voor Blazor WebAssembly via een NuGet-pakket", samen met de drie subsecties, gedetailleerde uitleg over de configuratie en code in het Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
-pakket. De gedetailleerde uitleg is belangrijk om te begrijpen wanneer u uw eigen strategie en aangepast laadproces voor Blazor WebAssembly apps maakt. Voer de volgende stappen uit om het gepubliceerde, experimentele, niet-ondersteunde NuGet-pakket zonder aanpassing te gebruiken als lokale demonstratie:
Gebruik een bestaande gehoste Blazor WebAssemblyoplossing of maak een nieuwe oplossing op basis van de Blazor WebAssembly projectsjabloon met visual Studio of door de optie
-ho|--hosted
door te geven aan de opdrachtdotnet new
(dotnet new blazorwasm -ho
). Zie Hulpprogramma's voor ASP.NET Core Blazorvoor meer informatie.Voeg in het Client-project het experimentele
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
-pakket toe.Notitie
Zie de artikelen onder Pakketten installeren en beheren bij Verbruikswerkstroom voor pakketten (NuGet-documentatie)voor hulp bij het toevoegen van pakketten aan .NET-apps. Bevestig de juiste pakketversies op NuGet.org.
Voeg in het Server project een eindpunt toe voor het leveren van het bundelbestand (
app.bundle
). Voorbeeldcode vindt u in de De bundel serveren vanaf de hostserver-app sectie van dit artikel.Publiceer de app in de Release-configuratie.
Het Blazor WebAssembly laadproces aanpassen via een NuGet-pakket
Waarschuwing
De richtlijnen in deze sectie met de drie subsecties hebben betrekking op het bouwen van een volledig nieuw NuGet-pakket om uw eigen strategie en aangepast laadproces te implementeren. De experimenteleMicrosoft.AspNetCore.Components.WebAssembly.MultipartBundle
pakket (NuGet.org) voor .NET 6 en 7 is gebaseerd op de richtlijnen in deze sectie. Wanneer u het meegeleverde pakket gebruikt in een lokale demonstratie van de downloadbenadering voor meerdere onderdelenbundels, hoeft u de richtlijnen in deze sectie niet te volgen. Zie de sectie Experimenteel NuGet-pakket en voorbeeld-app voor hulp bij het gebruik van het meegeleverde pakket.
Blazor app-resources zijn ingepakt in een bundelbestand met meerdere onderdelen en geladen door de browser via een aangepaste JavaScript (JS) initialisatiefunctie. Voor een app die het pakket gebruikt met de JS initialisatiefunctie, vereist de app alleen dat het bundelbestand wordt geleverd wanneer dit wordt aangevraagd. Alle andere aspecten van deze aanpak worden transparant afgehandeld.
Er zijn vier aanpassingen vereist om te bepalen hoe een standaard gepubliceerde Blazor-app wordt geladen:
- Een MSBuild-taak om de publicatiebestanden te transformeren.
- Een NuGet-pakket met MSBuild-doelen die aansluiten op het Blazor-publicatieproces, de uitvoer transformeert en een of meer Blazor-publicatie-extensiebestanden definieert (in dit geval een enkele bundel).
- Een JS initializer om de callback van het Blazor WebAssembly resourcelaadprogramma bij te werken zodat de bundel wordt geladen en de app de individuele bestanden beschikbaar stelt.
- Een helper op de host Server app om ervoor te zorgen dat de bundel op verzoek aan clients wordt geleverd.
Een MSBuild-taak maken om de lijst met gepubliceerde bestanden aan te passen en nieuwe extensies te definiëren
Maak een MSBuild-taak als een openbare C#-klasse die kan worden geïmporteerd als onderdeel van een MSBuild-compilatie en die kan communiceren met de build.
Het volgende is vereist voor de C#-klasse:
- Een nieuw klassebibliotheekproject.
- Een projectdoelframework van
netstandard2.0
. - Verwijzingen naar MSBuild-pakketten:
Notitie
Het NuGet-pakket voor de voorbeelden in dit artikel heeft de naam van het pakket van Microsoft, Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
. Zie de volgende NuGet-artikelen voor hulp bij het benoemen en produceren van uw eigen NuGet-pakket:
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.csproj
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build.Framework" Version="{VERSION}" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="{VERSION}" />
</ItemGroup>
</Project>
Bepaal de nieuwste pakketversies voor de {VERSION}
plaatsaanduidingen op NuGet.org:
Als u de MSBuild-taak wilt maken, maakt u een openbare C#-klasse die Microsoft.Build.Utilities.Task uitbreidt (niet System.Threading.Tasks.Task) en declareert u drie eigenschappen:
-
PublishBlazorBootStaticWebAsset
: de lijst met bestanden die moeten worden gepubliceerd voor de Blazor-app. -
BundlePath
: het pad waar de bundel is geschreven. -
Extension
: de nieuwe publicatie-extensies die moeten worden opgenomen in de build.
Het volgende voorbeeld BundleBlazorAssets
klasse is een startpunt voor verdere aanpassing:
- In de methode
Execute
wordt de bundel gemaakt op basis van de volgende drie bestandstypen:- JavaScript-bestanden (
dotnet.js
) - WASM-bestanden (
dotnet.wasm
) - App DLLs (
.dll
)
- JavaScript-bestanden (
- Er wordt een
multipart/form-data
bundel gemaakt. Elk bestand wordt aan de bundel toegevoegd met de bijbehorende beschrijvingen via de Content-Disposition-header en de Content-Type-header. - Nadat de bundel is gemaakt, wordt de bundel naar een bestand geschreven.
- De build is geconfigureerd voor de extensie. Met de volgende code wordt een extensie-item gemaakt en toegevoegd aan de eigenschap
Extension
. Elk extensie-item bevat drie stukjes gegevens:- Het pad naar het extensiebestand.
- Het URL-pad ten opzichte van de hoofddirectory van de Blazor WebAssembly-app.
- De naam van de extensie, die de bestanden groeperen die zijn geproduceerd door een bepaalde extensie.
Nadat u de voorgaande doelen hebt bereikt, wordt de MSBuild-taak gemaakt voor het aanpassen van de publicatie-uitvoer van Blazor.
Blazor zorgt ervoor dat de extensies worden verzameld en ervoor zorgen dat de extensies worden gekopieerd naar de juiste locatie in de publicatieuitvoermap (bijvoorbeeld bin\Release\net6.0\publish
). Dezelfde optimalisaties (bijvoorbeeld compressie) worden toegepast op de JavaScript-, WASM- en DLL-bestanden als Blazor van toepassing is op andere bestanden.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks/BundleBlazorAssets.cs
:
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks
{
public class BundleBlazorAssets : Task
{
[Required]
public ITaskItem[]? PublishBlazorBootStaticWebAsset { get; set; }
[Required]
public string? BundlePath { get; set; }
[Output]
public ITaskItem[]? Extension { get; set; }
public override bool Execute()
{
var bundle = new MultipartFormDataContent(
"--0a7e8441d64b4bf89086b85e59523b7d");
foreach (var asset in PublishBlazorBootStaticWebAsset)
{
var name = Path.GetFileName(asset.GetMetadata("RelativePath"));
var fileContents = File.OpenRead(asset.ItemSpec);
var content = new StreamContent(fileContents);
var disposition = new ContentDispositionHeaderValue("form-data");
disposition.Name = name;
disposition.FileName = name;
content.Headers.ContentDisposition = disposition;
var contentType = Path.GetExtension(name) switch
{
".js" => "text/javascript",
".wasm" => "application/wasm",
_ => "application/octet-stream"
};
content.Headers.ContentType =
MediaTypeHeaderValue.Parse(contentType);
bundle.Add(content);
}
using (var output = File.Open(BundlePath, FileMode.OpenOrCreate))
{
output.SetLength(0);
bundle.CopyToAsync(output).ConfigureAwait(false).GetAwaiter()
.GetResult();
output.Flush(true);
}
var bundleItem = new TaskItem(BundlePath);
bundleItem.SetMetadata("RelativePath", "app.bundle");
bundleItem.SetMetadata("ExtensionName", "multipart");
Extension = new ITaskItem[] { bundleItem };
return true;
}
}
}
Een NuGet-pakket ontwerpen om de publicatie-uitvoer automatisch te transformeren
Genereer een NuGet-pakket met MSBuild-doelen die automatisch worden opgenomen wanneer naar het pakket wordt verwezen:
- Maak een nieuw Razor class library (RCL) project.
- Maak een doelenbestand volgens NuGet-conventies om het pakket automatisch te importeren in verbruikende projecten. Maak bijvoorbeeld
build\net6.0\{PACKAGE ID}.targets
, waarbij{PACKAGE ID}
de pakket-id van het pakket is. - Verzamel de uitvoer van de klassebibliotheek met de MSBuild-taak en controleer of de uitvoer op de juiste locatie is verpakt.
- Voeg de benodigde MSBuild-code toe om te koppelen aan de Blazor-pijplijn en roep de MSBuild-taak aan om de bundel te genereren.
De benadering die in deze sectie wordt beschreven, gebruikt alleen het pakket om doelen en inhoud te leveren, wat verschilt van de meeste pakketten waarin het pakket een bibliotheek-DLL bevat.
Waarschuwing
Het voorbeeldpakket dat in deze sectie wordt beschreven, laat zien hoe u het Blazor publicatieproces aanpast. Het NuGet-voorbeeldpakket is alleen bedoeld voor gebruik als lokale demonstratie. Het gebruik van dit pakket in productie wordt niet ondersteund.
Notitie
Het NuGet-pakket voor de voorbeelden in dit artikel heeft de naam van het pakket van Microsoft, Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
. Zie de volgende NuGet-artikelen voor hulp bij het benoemen en produceren van uw eigen NuGet-pakket:
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.csproj
:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<NoWarn>NU5100</NoWarn>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Description>
Sample demonstration package showing how to customize the Blazor publish
process. Using this package in production is not supported!
</Description>
<IsPackable>true</IsPackable>
<IsShipping>true</IsShipping>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<None Update="build\**"
Pack="true"
PackagePath="%(Identity)" />
<Content Include="_._"
Pack="true"
PackagePath="lib\net6.0\_._" />
</ItemGroup>
<Target Name="GetTasksOutputDlls"
BeforeTargets="CoreCompile">
<MSBuild Projects="..\Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks\Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.csproj"
Targets="Publish;PublishItemsOutputGroup"
Properties="Configuration=Release">
<Output TaskParameter="TargetOutputs"
ItemName="_TasksProjectOutputs" />
</MSBuild>
<ItemGroup>
<Content Include="@(_TasksProjectOutputs)"
Condition="'%(_TasksProjectOutputs.Extension)' == '.dll'"
Pack="true"
PackagePath="tasks\%(_TasksProjectOutputs.TargetPath)"
KeepMetadata="Pack;PackagePath" />
</ItemGroup>
</Target>
</Project>
Notitie
De eigenschap <NoWarn>NU5100</NoWarn>
in het vorige voorbeeld onderdrukt de waarschuwing over de assembly's die in de map tasks
zijn geplaatst. Zie NuGet-waarschuwing NU5100voor meer informatie.
Voeg een .targets
-bestand toe om de MSBuild-taak aan de build-pijplijn te koppelen. In dit bestand worden de volgende doelen bereikt:
- Importeer de taak in het buildproces. Houd er rekening mee dat het pad naar het DLL-bestand relatief is ten opzichte van de uiteindelijke locatie van het bestand in het pakket.
- De eigenschap
ComputeBlazorExtensionsDependsOn
koppelt het aangepaste doel aan de Blazor WebAssembly-pijplijn. - Leg de eigenschap
Extension
vast in de taakuitvoer en voeg deze toe aanBlazorPublishExtension
om Blazor over de extensie te vertellen. Als u de taak in het doel aanroept, wordt de bundel geproduceerd. De lijst met gepubliceerde bestanden wordt geleverd door de Blazor WebAssembly pijplijn in dePublishBlazorBootStaticWebAsset
itemgroep. Het bundelpad wordt gedefinieerd met behulp van deIntermediateOutputPath
(meestal in de mapobj
). Uiteindelijk wordt de bundel automatisch gekopieerd naar de juiste locatie in de publicatie-uitvoermap (bijvoorbeeldbin\Release\net6.0\publish
).
Wanneer naar het pakket wordt verwezen, wordt er tijdens het publiceren een bundel van de Blazor bestanden gegenereerd.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/build/net6.0/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.targets
:
<Project>
<UsingTask
TaskName="Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.BundleBlazorAssets"
AssemblyFile="$(MSBuildThisProjectFileDirectory)..\..\tasks\Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.dll" />
<PropertyGroup>
<ComputeBlazorExtensionsDependsOn>
$(ComputeBlazorExtensionsDependsOn);_BundleBlazorDlls
</ComputeBlazorExtensionsDependsOn>
</PropertyGroup>
<Target Name="_BundleBlazorDlls">
<BundleBlazorAssets
PublishBlazorBootStaticWebAsset="@(PublishBlazorBootStaticWebAsset)"
BundlePath="$(IntermediateOutputPath)bundle.multipart">
<Output TaskParameter="Extension"
ItemName="BlazorPublishExtension"/>
</BundleBlazorAssets>
</Target>
</Project>
Automatisch Blazor uit het pakket opstarten
Het NuGet-pakket maakt gebruik van JavaScript -initialisatieprogramma's (JS) om automatisch een Blazor WebAssembly-app uit de bundel te bootsen in plaats van afzonderlijke DLL-bestanden te gebruiken. JS initializers worden gebruikt om de Blazoropstartresourcesloader te wijzigen en de bundel te gebruiken.
Als u een JS initialisatiefunctie wilt maken, voegt u een JS bestand met de naam {NAME}.lib.module.js
toe aan de map wwwroot
van het pakketproject, waarbij de tijdelijke aanduiding voor {NAME}
de pakket-id is. Het bestand voor het Microsoft-pakket heeft bijvoorbeeld de naam Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
. De geëxporteerde functies beforeWebAssemblyStart
en afterWebAssemblyStarted
beheren het laden.
De JS initializers:
- Detecteer of de publicatie-extensie beschikbaar is door te controleren op
extensions.multipart
, de extensienaam (ExtensionName
) die is opgegeven in de Een MSBuild-taak maken om de lijst met gepubliceerde bestanden aan te passen en nieuwe extensies sectie te definiëren. - Download de bundel en parseert de inhoud in een resourcesoverzicht met behulp van gegenereerde object-URL's.
- Werk het laadprogramma voor opstartresources (
options.loadBootResource
) bij met een aangepaste functie waarmee de resources worden omgezet met behulp van de object-URL's. - Nadat de app is gestart, herroept u de object-URL's om geheugen vrij te geven in de
afterWebAssemblyStarted
-functie.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/wwwroot/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
:
const resources = new Map();
export async function beforeWebAssemblyStart(options, extensions) {
if (!extensions || !extensions.multipart) {
return;
}
try {
const integrity = extensions.multipart['app.bundle'];
const bundleResponse =
await fetch('app.bundle', { integrity: integrity, cache: 'no-cache' });
const bundleFromData = await bundleResponse.formData();
for (let value of bundleFromData.values()) {
resources.set(value, URL.createObjectURL(value));
}
options.loadBootResource = function (type, name, defaultUri, integrity) {
return resources.get(name) ?? null;
}
} catch (error) {
console.log(error);
}
}
export async function afterWebAssemblyStarted(blazor) {
for (const [_, url] of resources) {
URL.revokeObjectURL(url);
}
}
Als u een JS initialisatiefunctie wilt maken, voegt u een JS bestand met de naam {NAME}.lib.module.js
toe aan de map wwwroot
van het pakketproject, waarbij de tijdelijke aanduiding voor {NAME}
de pakket-id is. Het bestand voor het Microsoft-pakket heeft bijvoorbeeld de naam Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
. De geëxporteerde functies beforeStart
en afterStarted
verwerken het laden.
De JS initializers:
- Detecteer of de publicatie-extensie beschikbaar is door te controleren op
extensions.multipart
, de extensienaam (ExtensionName
) die is opgegeven in de Een MSBuild-taak maken om de lijst met gepubliceerde bestanden aan te passen en nieuwe extensies sectie te definiëren. - Download de bundel en parseert de inhoud in een resourcesoverzicht met behulp van gegenereerde object-URL's.
- Werk de boot-resourceloader (
options.loadBootResource
) bij met een aangepaste functie die de resources oplost met behulp van de object-URL's. - Nadat de app is gestart, trekt u de URL's van objecten in om geheugen vrij te geven in de functie
afterStarted
.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/wwwroot/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
:
const resources = new Map();
export async function beforeStart(options, extensions) {
if (!extensions || !extensions.multipart) {
return;
}
try {
const integrity = extensions.multipart['app.bundle'];
const bundleResponse =
await fetch('app.bundle', { integrity: integrity, cache: 'no-cache' });
const bundleFromData = await bundleResponse.formData();
for (let value of bundleFromData.values()) {
resources.set(value, URL.createObjectURL(value));
}
options.loadBootResource = function (type, name, defaultUri, integrity) {
return resources.get(name) ?? null;
}
} catch (error) {
console.log(error);
}
}
export async function afterStarted(blazor) {
for (const [_, url] of resources) {
URL.revokeObjectURL(url);
}
}
Dien de bundel op vanaf de hostserver-app
Vanwege beveiligingsbeperkingen biedt ASP.NET Core het app.bundle
-bestand niet. Een helper voor het verwerken van aanvragen is vereist om het bestand te verwerken wanneer het door clients wordt aangevraagd.
Notitie
Aangezien dezelfde optimalisaties transparant worden toegepast op de publicatie-extensies die worden toegepast op de bestanden van de app, worden de app.bundle.gz
- en app.bundle.br
gecomprimeerde assetbestanden automatisch geproduceerd bij publiceren.
Plaats C#-code in Program.cs
van het Server-project direct voor de regel waarmee het terugvalbestand wordt ingesteld op index.html
(app.MapFallbackToFile("index.html");
) om te reageren op een aanvraag voor het bundelbestand (bijvoorbeeld app.bundle
):
app.MapGet("app.bundle", (HttpContext context) =>
{
string? contentEncoding = null;
var contentType =
"multipart/form-data; boundary=\"--0a7e8441d64b4bf89086b85e59523b7d\"";
var fileName = "app.bundle";
var acceptEncodings = context.Request.Headers.AcceptEncoding;
if (Microsoft.Net.Http.Headers.StringWithQualityHeaderValue
.StringWithQualityHeaderValue
.TryParseList(acceptEncodings, out var encodings))
{
if (encodings.Any(e => e.Value == "br"))
{
contentEncoding = "br";
fileName += ".br";
}
else if (encodings.Any(e => e.Value == "gzip"))
{
contentEncoding = "gzip";
fileName += ".gz";
}
}
if (contentEncoding != null)
{
context.Response.Headers.ContentEncoding = contentEncoding;
}
return Results.File(
app.Environment.WebRootFileProvider.GetFileInfo(fileName)
.CreateReadStream(), contentType);
});
Het inhoudstype komt overeen met het type dat eerder in de build-taak is gedefinieerd. Het eindpunt controleert welke inhoudscoderingen door de browser worden geaccepteerd en levert het optimale bestand, Brotli (.br
) of Gzip (.gz
).