A ASP.NET Core 9.0 újdonságai
Ez a cikk a ASP.NET Core 9.0 legfontosabb változásait emeli ki a vonatkozó dokumentációra mutató hivatkozásokkal.
Statikus eszközkézbesítés optimalizálása
MapStaticAssets
az útválasztási végpontok konvenciói egy új funkció, amely optimalizálja a statikus eszközök kézbesítését az ASP.NET Core alkalmazásokban.
Az Blazor-alkalmazások statikus eszközkézbesítésére vonatkozó információkért lásd a ASP.NET Core Blazor statikus fájlokat.
A statikus eszközök kiszolgálásához ajánlott gyártási eljárások követése jelentős mennyiségű munkát és műszaki szakértelmet igényel. Optimalizálások, például tömörítés, gyorsítótárazás és ujjlenyomatok nélkül:
- A böngészőnek további kéréseket kell küldenie minden oldalbetöltéshez.
- A szükségesnél több bájt kerül átvitelre a hálózaton keresztül.
- Néha elavult verziók kerülnek kiszolgálásra az ügyfelek számára.
A teljesítményalapú webalkalmazások létrehozásához optimalizálni kell az eszközök böngészőbe történő kézbesítését. A lehetséges optimalizálások a következők:
- Egy adott objektumot egyszer kell kiszolgálni, amíg a fájl nem változik, vagy a böngésző nem törli a gyorsítótárát. Állítsa be a ETag fejlécet.
- Megakadályozza, hogy a böngésző régi vagy elavult objektumokat használ az alkalmazás frissítése után. Állítsa be a utoljára módosított fejlécet.
- Állítsa be a megfelelő gyorsítótárazási fejléceket.
- Használja a gyorsítótárazó köztes szoftvert.
- tömörített-verziókat szolgáljanak ki, ha lehetséges.
- Használjon egy CDN- az eszközök felhasználóhoz közelebbi kiszolgálásához.
- A böngészőnek kiszolgált objektumok méretének minimalizálása. Ez az optimalizálás nem tartalmazza a minifikációt.
MapStaticAssets egy új funkció, amely optimalizálja a statikus eszközök kézbesítését egy alkalmazásban. Úgy tervezték, hogy minden felhasználói felületi keretrendszerrel működjön, beleértve a Blazor, a Razor Pages és az MVC-t. Ez általában egy könnyen beilleszthető helyettesítő a UseStaticFiles
számára.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
+app.MapStaticAssets();
-app.UseStaticFiles();
app.MapRazorPages();
app.Run();
MapStaticAssets
a buildelési és közzétételi idő folyamatok kombinálásával gyűjti össze az alkalmazás összes statikus erőforrásával kapcsolatos információkat. Ezt az információt a futtatókörnyezeti kódtár használja fel, hogy hatékonyan kiszolgálja ezeket a fájlokat a böngészőben.
MapStaticAssets
a legtöbb helyzetben lecserélheti a UseStaticFiles
-et, azonban az alkalmazás által a buildelés és a közzététel ideje alatt megismert eszközök kiszolgálására van optimalizálva. Ha az alkalmazás más helyekről, például lemezről vagy beágyazott erőforrásokból származó eszközöket szolgál ki, UseStaticFiles
kell használni.
MapStaticAssets
a következő, a UseStaticFiles
-nél nem található előnyöket nyújtja:
- Időtömörítés létrehozása az alkalmazás összes eszközéhez:
-
gzip
a fejlesztés alatt ésgzip + brotli
a közzététel alatt. - Minden eszköz tömörítve van azzal a céllal, hogy az eszközök méretét a lehető legkisebbre csökkentse.
-
- Tartalomalapú
: Az egyes erőforrásokhoz tartozó a SHA-256 kivonat tartalmának Base64 formátumban kódoltsztringje. Ez biztosítja, hogy a böngésző csak akkor töltse újra újra a fájlt, ha a tartalma megváltozott.
Az alábbi táblázat a CSS és JS fájlok eredeti és tömörített méretét mutatja az alapértelmezett Razor Pages-sablonban:
Fájl | Eredeti | Tömörített | % csökkentés |
---|---|---|---|
bootstrap.min.css | 163 | 17.5 | 89.26% |
jquery.js | 89.6 | 28 | 68.75% |
bootstrap.min.js | 78.5 | 20 | 74.52% |
Összes | 331.1 | 65.5 | 80.20% |
Az alábbi táblázat az eredeti és a tömörített méreteket mutatja be a Fluent felhasználói felületi Blazor összetevőtárhasználatával:
Fájl | Eredeti | Tömörített | % csökkentés |
---|---|---|---|
fluent.js | 384 | 73 | 80,99% |
fluent.css | 94 | 11 | 88.30% |
Összes | 478 | 84 | 82.43% |
A 478 KB tömörítetlenből 84 KB tömörített lett.
Az alábbi táblázat az eredeti és a tömörített méreteket mutatja be a MudBlazorBlazor összetevőtár használatával:
Fájl | Eredeti | Tömörített | Csökkentés |
---|---|---|---|
MudBlazor.min.css | 541 | 37.5 | 93.07% |
MudBlazor.min.js | 47.4 | 9.2 | 80,59% |
Összes | 588.4 | 46.7 | 92.07% |
Az optimalizálás automatikusan történik MapStaticAssets
használatakor. Ha hozzáad vagy frissít egy kódtárat, például új JavaScript vagy CSS használatával, az eszközök a build részeként lesznek optimalizálva. Az optimalizálás különösen előnyös az alacsonyabb sávszélességű vagy megbízhatatlan kapcsolatokkal rendelkező mobilkörnyezetek számára.
Az új fájlkézbesítési funkciókról az alábbi forrásokból tájékozódhat:
Dinamikus tömörítés engedélyezése a kiszolgálón vs MapStaticAssets
használata.
MapStaticAssets
a következő előnyökkel rendelkezik a kiszolgáló dinamikus tömörítésével szemben:
- Egyszerűbb, mert nincs kiszolgálóspecifikus konfiguráció.
- Nagyobb teljesítményű, mert az objektumok tömörítése a létrehozáskor történik.
- Lehetővé teszi a fejlesztő számára, hogy a buildelési folyamat során több időt töltsön annak érdekében, hogy az eszközök a minimális méretűek legyenek.
Vegye figyelembe az alábbi táblázatot, amely összehasonlítja a MudBlazor tömörítést az IIS dinamikus tömörítésével és MapStaticAssets
:
IIS gzip | MapStaticAssets |
MapStaticAssets csökkentése |
---|---|---|
≅ 90 | 37.5 | 59% |
Blazor
Ez a szakasz a Blazorúj funkcióit ismerteti.
.NET MAUI Blazor Hybrid és Web App-megoldássablon
Egy új megoldássablon megkönnyíti .NET MAUI natív és Blazor azonos felhasználói felülettel rendelkező webes ügyfélalkalmazások létrehozását. Ez a sablon bemutatja, hogyan hozhat létre olyan ügyfélalkalmazásokat, amelyek maximalizálják a kód újrafelhasználását és célként az Android, iOS, Mac, Windows és Web rendszert.
A sablon főbb funkciói a következők:
- A Blazor interaktív renderelési mód kiválasztásának lehetősége a webalkalmazáshoz.
- A megfelelő projektek automatikus létrehozása, beleértve egy Blazor Web App (globális interaktív automatikus renderelés) és egy .NET MAUIBlazor Hybrid alkalmazás létrehozását.
- A létrehozott projektek megosztott Razor osztálytárat (RCL) használnak a felhasználói felület Razor összetevőinek karbantartásához.
- A mintakód bemutatja, hogyan használható függőséginjektálás az Blazor Hybrid alkalmazás és a Blazor Web Appkülönböző felületi implementációinak biztosítására.
Első lépésként telepítse a .NET 9 SDK és telepítse a sablont tartalmazó .NET MAUI számítási feladatot:
dotnet workload install maui
Hozzon létre egy megoldást a projektsablonból egy parancshéjban a következő paranccsal:
dotnet new maui-blazor-web
A sablon a Visual Studióban is elérhető.
Jegyzet
Jelenleg kivétel történik, ha Blazor renderelési módok az oldal/összetevő szintjén vannak definiálva. További információért lásd: a BlazorWebView-nak engedélyeznie kell a ResolveComponentForRenderMode (dotnet/aspnetcore
#51235)felülbírálását.
További információért lásd: .NET MAUIBlazor Hybrid alkalmazás létrehozása Blazor Web App.
A renderelési hely, az interaktivitás és a hozzárendelt renderelési mód észlelése futásidőben
Bevezettünk egy új API-t, amely leegyszerűsíti az összetevők állapotainak futásidőben történő lekérdezését. Ez az API a következő képességeket biztosítja:
- Az összetevő aktuális végrehajtási helyének meghatározása: Ez hasznos lehet az összetevők teljesítményének hibakereséséhez és optimalizálásához.
- Ellenőrizze, hogy az összetevő interaktív környezetben fut-e: Ez hasznos lehet azoknak az összetevőknek, amelyek a környezetük interaktivitása alapján eltérő viselkedéssel rendelkeznek.
- Az összetevőhöz rendelt renderelési mód lekérése: A renderelési mód megismerése segíthet a renderelési folyamat optimalizálásában és az összetevők általános teljesítményének javításában.
További információ: ASP.NET Core Blazor renderelési módok.
Továbbfejlesztett kiszolgálóoldali újracsatlakozási élmény:
A következő fejlesztések történtek az alapértelmezett kiszolgálóoldali újracsatlakozási felületen:
Amikor a felhasználó egy leválasztott kapcsolatcsoporttal rendelkező alkalmazásra lép vissza, a rendszer azonnal megkísérli az újracsatlakozást ahelyett, hogy a következő újracsatlakozási időköz időtartamára várna. Ez javítja a felhasználói élményt, amikor egy olyan alkalmazásra navigál egy böngészőlapon, amely alvó állapotba került.
Amikor egy újracsatlakozási kísérlet eléri a kiszolgálót, de a kiszolgáló már kiadta a kapcsolatot, a lap automatikusan frissül. Ez megakadályozza, hogy a felhasználó manuálisan frissítse a lapot, ha az valószínűleg sikeres újracsatlakozást eredményez.
Az újracsatlakozás időzítése egy kiszámított hátrálási stratégiát használ. Alapértelmezés szerint az első több újracsatlakozási kísérlet gyors egymásutánban történik újrapróbálkozási időköz nélkül, mielőtt a kísérletek között kiszámított késések lépnek fel. Az újrapróbálkozási időköz viselkedését úgy szabhatja testre, hogy megad egy függvényt az újrapróbálkozási időköz kiszámításához, ahogy az alábbi exponenciális visszalépési példa is mutatja:
Blazor.start({ circuit: { reconnectionOptions: { retryIntervalMilliseconds: (previousAttempts, maxRetries) => previousAttempts >= maxRetries ? null : previousAttempts * 1000 }, }, });
Az alapértelmezett újrakapcsolódási felhasználói felület stílusa modernizálva lett.
További információ: ASP.NET Core BlazorSignalR útmutató.
Egyszerűsített hitelesítési állapot szerializálása Blazor Web Apps-hez
Az új API-k megkönnyítik a hitelesítés hozzáadását egy meglévő Blazor Web App. Amikor új Blazor Web App-t hoz létre, hitelesítéssel egyéni fiókok használatával, és engedélyezi a WebAssembly-alapú interaktivitást, a projekt mind a kiszolgáló-, mind az ügyfélprojektek tartalmaz egy egyéni AuthenticationStateProvider-at.
Ezek a szolgáltatók továbbítják a felhasználó hitelesítési állapotát a böngészőbe. Az ügyfél helyett a kiszolgálón történő hitelesítés lehetővé teszi az alkalmazás számára a hitelesítési állapot elérését az előrendelés során és a .NET WebAssembly futtatókörnyezet inicializálása előtt.
Az egyéni AuthenticationStateProvider-implementációk az Állandó összetevő állapota szolgáltatás (PersistentComponentState) használatával szerializálják a hitelesítési állapotot HTML-megjegyzésekké, és a WebAssemblyből olvassák vissza egy új AuthenticationState-példány létrehozásához.
Ez akkor működik jól, ha a Blazor Web App projektsablonból indult, és kiválasztotta az Egyéni fiókok lehetőséget, de sok kóddal valósíthatja meg saját magát, vagy másolhatja, ha hitelesítést próbál hozzáadni egy meglévő projekthez. A Blazor Web App projektsablon részét képező API-k mostantól meghívhatók a kiszolgálói és ügyfélprojektekben a funkció hozzáadásához:
- AddAuthenticationStateSerialization: Hozzáadja a kiszolgáló hitelesítési állapotának szerializálásához szükséges szolgáltatásokat.
- AddAuthenticationStateDeserialization: Hozzáadja a böngésző hitelesítési állapotának deszerializálásához szükséges szolgáltatásokat.
Alapértelmezés szerint az API csak a böngészőben való hozzáférés kiszolgálóoldali nevét és szerepkör-jogcímeit szerializálja. Az összes jogcím belefoglalásához a AddAuthenticationStateSerialization számára megadható egy lehetőség.
További információt a ASP.NET Core Blazor hitelesítés és engedélyezésalábbi szakaszaiban talál:
Statikus kiszolgálóoldali renderelési (SSR-) oldalak hozzáadása egy globálisan interaktívvá váló Blazor Web App-hoz.
A .NET 9 kiadásával mostantól egyszerűbb statikus SSR-oldalakat hozzáadni a globális interaktivitást alkalmazó alkalmazásokhoz.
Ez a módszer csak akkor hasznos, ha az alkalmazás olyan lapokkal rendelkezik, amelyek nem használhatók interaktív kiszolgáló- vagy WebAssembly-rendereléssel. Ez a megközelítés például olyan oldalak esetében alkalmazható, amelyek HTTP-cookie-k olvasásától/írásától függenek, és interaktív renderelés helyett csak kérés-válasz ciklusban működnek. Az interaktív rendereléssel dolgozó lapok esetében nem szabad statikus SSR-renderelésre kényszeríteni őket, mivel az kevésbé hatékony és kevésbé rugalmas a végfelhasználó számára.
Jelölje meg az Razor összetevőlapokat az [ExcludeFromInteractiveRouting]
irányelvhez hozzárendelt új @attribute
:
@attribute [ExcludeFromInteractiveRouting]
Az attribútum alkalmazása esetén a lapra való navigálás kilép az interaktív útválasztásból. A bejövő navigációnál egy teljes oldalt újra kell tölteni, ahelyett, hogy interaktív útválasztással megoldják az oldalt. A teljes oldal újrabetöltése kényszeríti a legfelső szintű gyökérösszetevőt, általában a App
összetevőt (App.razor
) a kiszolgálóról való újrarendelésre, lehetővé téve az alkalmazás számára, hogy másik legfelső szintű renderelési módra váltson.
A RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting bővítménymetódus lehetővé teszi, hogy az összetevő észlelje, hogy a [ExcludeFromInteractiveRouting]
attribútum van-e alkalmazva az aktuális lapra.
Az App
összetevőben használja a következő példában szereplő mintát:
- A
[ExcludeFromInteractiveRouting]
attribútummal nem jegyzett lapok alapértelmezetten aInteractiveServer
renderelési módra globális interaktivitással. A másik alapértelmezett globális renderelési mód megadásához lecserélheti aInteractiveServer
-etInteractiveWebAssembly
-re vagyInteractiveAuto
-re. - A
[ExcludeFromInteractiveRouting]
attribútummal jegyzett lapok statikus SSR-t fogadnak el (PageRenderMode
null
van hozzárendelve).
<!DOCTYPE html>
<html>
<head>
...
<HeadOutlet @rendermode="@PageRenderMode" />
</head>
<body>
<Routes @rendermode="@PageRenderMode" />
...
</body>
</html>
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? PageRenderMode
=> HttpContext.AcceptsInteractiveRouting() ? InteractiveServer : null;
}
A RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting bővítménymetódus használatának alternatívája a végpont metaadatainak manuális olvasása a HttpContext.GetEndpoint()?.Metadata
használatával.
Ezt a funkciót a ASP.NET Core Blazor renderelési módjának referenciadokumentációjatartalmazza.
Konstruktor injektálás
Razor összetevők támogatják a konstruktorinjektálást.
Az alábbi példában a részleges (kód mögötti) osztály egy NavigationManager
használatával injektálja a szolgáltatást:
public partial class ConstructorInjection(NavigationManager navigation)
{
private void HandleClick()
{
navigation.NavigateTo("/counter");
}
}
További információért lásd a ASP.NET Core Blazor függőség-injektálás.
Websocket-tömörítés interaktív kiszolgáló-összetevőkhöz
Az interaktív kiszolgáló összetevői alapértelmezés szerint lehetővé teszik WebSocket-kapcsolatok tömörítését, és beállítanak egy frame-ancestors
tartalombiztonsági szabályzatot (CSP) irányelv 'self'
, amely csak az alkalmazásnak az alkalmazás forrásának <iframe>
való beágyazását teszi lehetővé a tömörítés engedélyezésekor vagy a WebSocket-környezet konfigurációjának megadásakor.
A tömörítés letiltható úgy, hogy ConfigureWebSocketOptions
null
értékre állítja, ami csökkenti az alkalmazás biztonsági rését a támadásához, de csökkentheti a teljesítményt:
.AddInteractiveServerRenderMode(o => o.ConfigureWebSocketOptions = null)
Konfiguráljon egy szigorúbb frame-ancestors
CSP-t 'none'
értékkel (egyetlen idézőjel szükséges), amely lehetővé teszi a WebSocket tömörítést, de megakadályozza, hogy a böngészők bármely <iframe>
-be ágyazzák az alkalmazást.
.AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = "'none'")
További információ:
- ASP.NET Core BlazorSignalR útmutatója
- Fenyegetésmérséklési útmutató az ASP.NET Core rendszerhez Blazor interaktív kiszolgálóoldali rendereléssel
Billentyűzetösszeállítási események kezelése a Blazor
Az új KeyboardEventArgs.IsComposing
tulajdonság azt jelzi, hogy a billentyűzetesemény egy összeállítási munkamenet része-e. A billentyűzetesemények összetételének nyomon követése elengedhetetlen a nemzetközi karakterbeviteli módszerek kezeléséhez.
Hozzáadta OverscanCount
paramétert a QuickGrid
A QuickGrid
összetevő mostantól egy OverscanCount
tulajdonságot tesz elérhetővé, amely meghatározza, hogy hány további sor jelenik meg a látható régió előtt és után, amikor engedélyezve van a virtualizálás.
Az alapértelmezett OverscanCount
3. A következő példa a OverscanCount
-t 4-re növeli.
<QuickGrid ItemsProvider="itemsProvider" Virtualize="true" OverscanCount="4">
...
</QuickGrid>
InputNumber
összetevő támogatja a type="range"
attribútumot
A InputNumber<TValue> összetevő mostantól támogatja a type="range"
attribútumot, amely egy olyan tartománybemenetet hoz létre, amely támogatja a modellkötést és az űrlapérvényesítést, amely általában csúszkaként vagy tárcsázóként jelenik meg szövegdoboz helyett:
<EditForm Model="Model" OnSubmit="Submit" FormName="EngineForm">
<div>
<label>
Nacelle Count (2-6):
<InputNumber @bind-Value="Model!.NacelleCount" max="6" min="2"
step="1" type="range" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm]
private EngineSpecifications? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() {}
public class EngineSpecifications
{
[Required, Range(minimum: 2, maximum: 6)]
public int NacelleCount { get; set; }
}
}
Új továbbfejlesztett navigációs események
JavaScript-visszahívások aktiválása a továbbfejlesztett navigáció előtt vagy után az új eseményfigyelőkkel:
blazor.addEventListener("enhancednavigationstart", {CALLBACK})
blazor.addEventListener("enhancednavigationend", {CALLBACK})
További információ: ASP.NET Core Blazor JavaScript statikus kiszolgálóoldali rendereléssel (statikus SSR).
SignalR
Ez a szakasz a SignalRúj funkcióit ismerteti.
Polimorf típus támogatás a SignalR csomópontokban
A központi metódusok mostantól elfogadnak egy alaposztályt a származtatott osztály helyett a polimorf forgatókönyvek engedélyezéséhez. Az alaptípust a polimorfizmusengedélyezéséhez
public class MyHub : Hub
{
public void Method(JsonPerson person)
{
if (person is JsonPersonExtended)
{
}
else if (person is JsonPersonExtended2)
{
}
else
{
}
}
}
[JsonPolymorphic]
[JsonDerivedType(typeof(JsonPersonExtended), nameof(JsonPersonExtended))]
[JsonDerivedType(typeof(JsonPersonExtended2), nameof(JsonPersonExtended2))]
private class JsonPerson
{
public string Name { get; set; }
public Person Child { get; set; }
public Person Parent { get; set; }
}
private class JsonPersonExtended : JsonPerson
{
public int Age { get; set; }
}
private class JsonPersonExtended2 : JsonPerson
{
public string Location { get; set; }
}
Továbbfejlesztett tevékenységek SignalR
SignalR most már rendelkezik activitySource-rel a központi kiszolgálóhoz és az ügyfélhez is.
.NET SignalR kiszolgálói ActivitySource
A SignalR ActivitySource nevű Microsoft.AspNetCore.SignalR.Server
központi metódushívások eseményeit bocsátja ki:
- Minden metódus saját tevékenység, így minden, ami a hub metódushívása során tevékenységet bocsát ki, a hub metódus tevékenységéhez tartozik.
- A központi metódustevékenységek nem rendelkeznek szülővel. Ez azt jelenti, hogy nincsenek csomagolva a hosszútávú SignalR kapcsolat alá.
Az alábbi példa az .NET Aspire irányítópult és a OpenTelemetry csomagokat használja:
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
Adja hozzá a következő indítási kódot a Program.cs
fájlhoz:
using OpenTelemetry.Trace;
using SignalRChat.Hubs;
// Set OTEL_EXPORTER_OTLP_ENDPOINT environment variable depending on where your OTEL endpoint is.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
if (builder.Environment.IsDevelopment())
{
// View all traces only in development environment.
tracing.SetSampler(new AlwaysOnSampler());
}
tracing.AddAspNetCoreInstrumentation();
tracing.AddSource("Microsoft.AspNetCore.SignalR.Server");
});
builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => tracing.AddOtlpExporter());
var app = builder.Build();
A következő példakimenet az Aspire irányítópultról származik:
.NET SignalR ügyfél tevékenységforrása
A SignalR nevű Microsoft.AspNetCore.SignalR.Client
ActivitySource eseményeket bocsát ki egy SignalR-ügyfél számára:
- A .NET SignalR-ügyfél neve
ActivitySource
Microsoft.AspNetCore.SignalR.Client
. A központi meghívások mostantól létrehoznak egy ügyféltartományt. Vegye figyelembe, hogy más SignalR ügyfelek, például a JavaScript-ügyfél nem támogatják a nyomkövetést. Ez a funkció a jövőbeni kiadásokban több ügyfélhez lesz hozzáadva. - Az ügyfél és a kiszolgáló központi hívásai támogatják környezetpropagálási. A nyomkövetési környezet propagálása lehetővé teszi a valódi elosztott nyomkövetést. Mostantól megtekintheti az ügyféltől a kiszolgálóig és vissza érkező hívásokat.
Az alábbi módon jelennek meg ezek az új tevékenységek az .NET Aspire irányítópult:
SignalR támogatja a vágást és a natív AOT-t
A .NET 8-ban megkezdett natív AOT-
Kezdés
Telepítse a legújabb .NET 9 SDK.
Hozzon létre egy megoldást a webapiaot
sablonból egy parancshéjban a következő paranccsal:
dotnet new webapiaot -o SignalRChatAOTExample
Cserélje le a Program.cs
fájl tartalmát a következő SignalR kódra:
using Microsoft.AspNetCore.SignalR;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.AddSignalR();
builder.Services.Configure<JsonHubProtocolOptions>(o =>
{
o.PayloadSerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
var app = builder.Build();
app.MapHub<ChatHub>("/chatHub");
app.MapGet("/", () => Results.Content("""
<!DOCTYPE html>
<html>
<head>
<title>SignalR Chat</title>
</head>
<body>
<input id="userInput" placeholder="Enter your name" />
<input id="messageInput" placeholder="Type a message" />
<button onclick="sendMessage()">Send</button>
<ul id="messages"></ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.7/signalr.min.js"></script>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.build();
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = `${user}: ${message}`;
document.getElementById("messages").appendChild(li);
});
async function sendMessage() {
const user = document.getElementById("userInput").value;
const message = document.getElementById("messageInput").value;
await connection.invoke("SendMessage", user, message);
}
connection.start().catch(err => console.error(err));
</script>
</body>
</html>
""", "text/html"));
app.Run();
[JsonSerializable(typeof(string))]
internal partial class AppJsonSerializerContext : JsonSerializerContext { }
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Az előző példa egy 10 MB-os natív Windows-futtatást és egy 10,9 MB-os Linux-futtatást eredményez.
Korlátozások
- Jelenleg csak a JSON protokoll támogatott:
- Az előző kódban látható módon a JSON szerializálást és natív AOT-t használó alkalmazásoknak a
System.Text.Json
Forrásgenerátort kell használniuk. - Ez ugyanazt a megközelítést követi, mint a minimális API-k.
- Az előző kódban látható módon a JSON szerializálást és natív AOT-t használó alkalmazásoknak a
- A SignalR kiszolgálón nem támogatottak az olyan
IAsyncEnumerable<T>
ésChannelReader<T>
típusú hubmetódus-paraméterek, ahol aT
ValueType (struct
) típusú. Az ilyen típusok használata futásidejű kivételt eredményez a fejlesztés indításakor és a közzétett alkalmazásban. További információért, nézze meg: SignalR: Az IAsyncEnumerable<T> és a ChannelReader<T> használata natív AOT-beli értéktípusokkal (dotnet/aspnetcore
#56179). -
Az erősen gépelt hubok nem támogatottak a natív AOT (
PublishAot
) használatával. Az erősen gépelt célhelyek natív AOT-val való használata figyelmeztetéseket eredményez a buildelés és a közzététel során, valamint futásidejű kivételt okozhat. Az erősen típusos hubok használata trimmeléssel (PublishedTrimmed
) támogatott. - Az aszinkron visszatérési típusok csak
Task
,Task<T>
,ValueTask
vagyValueTask<T>
támogatottak.
Minimális API-k
Ez a szakasz a minimális API-k új funkcióit ismerteti.
Hozzáadtuk InternalServerError
-t és InternalServerError<TValue>
-t a TypedResults
-höz
A TypedResults osztály egy hasznos eszköz, amely egy minimális API-ból származó, erősen gépelt HTTP-állapotkódon alapuló válaszokat ad vissza.
TypedResults
mostantól gyári metódusokat és típusokat is tartalmaz az "500 belső kiszolgálóhiba" válaszok végpontokról való visszaadására. Íme egy példa, amely 500 választ ad vissza:
var app = WebApplication.Create();
app.MapGet("/", () => TypedResults.InternalServerError("Something went wrong!"));
app.Run();
Hívás ProducesProblem
és ProducesValidationProblem
útvonalcsoportokon
A ProducesProblem
és ProducesValidationProblem
kiterjesztési módszereket frissítették azon való használatuk támogatására az útvonalcsoportokon. Ezek a módszerek azt jelzik, hogy egy útvonalcsoport összes végpontja ProblemDetails
vagy ValidationProblemDetails
válaszokat adhat vissza OpenAPI-metaadatok céljából.
var app = WebApplication.Create();
var todos = app.MapGroup("/todos")
.ProducesProblem();
todos.MapGet("/", () => new Todo(1, "Create sample app", false));
todos.MapPost("/", (Todo todo) => Results.Ok(todo));
app.Run();
record Todo(int Id, string Title, boolean IsCompleted);
Problem
és ValidationProblem
eredménytípusok támogatják az IEnumerable<KeyValuePair<string, object?>>
értékekkel való építkezést
A .NET 9 előtt a probléma és ValidationProblem eredménytípusok minimális API-kban történő létrehozásához a errors
és extensions
tulajdonságok inicializálása szükséges a IDictionary<string, object?>
implementációjával. Ebben a kiadásban ezek az építési API-k támogatják a IEnumerable<KeyValuePair<string, object?>>
-t használó túlterheléseket is.
var app = WebApplication.Create();
app.MapGet("/", () =>
{
var extensions = new List<KeyValuePair<string, object?>> { new("test", "value") };
return TypedResults.Problem("This is an error with extensions",
extensions: extensions);
});
Köszönet a GitHub felhasználói joegoldman2 a hozzájárulásért!
OpenAPI
Ez a szakasz az OpenAPI új funkcióit ismerteti
Az OpenAPI-dokumentumlétrehozás beépített támogatása
A OpenAPI-specifikáció a HTTP API-k leírásának szabványa. A szabvány lehetővé teszi a fejlesztők számára, hogy meghatározzák az ügyfélgenerátorokhoz, kiszolgálógenerátorokhoz, tesztelési eszközökhöz, dokumentációhoz stb. csatlakoztatható API-k alakját. A .NET 9-ben a ASP.NET Core beépített támogatást nyújt a vezérlőalapú vagy minimális API-kat képviselő OpenAPI-dokumentumok létrehozásához a Microsoft.AspNetCore.OpenApi csomagon keresztül.
A következő kiemelt kódhívások:
-
AddOpenApi
regisztrálni a szükséges függőségeket az alkalmazás DI-tárolójában. -
MapOpenApi
regisztrálni a szükséges OpenAPI-végpontokat az alkalmazás útvonalai között.
var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.MapGet("/hello/{name}", (string name) => $"Hello {name}"!);
app.Run();
Telepítse a Microsoft.AspNetCore.OpenApi
csomagot a projektben az alábbi paranccsal:
dotnet add package Microsoft.AspNetCore.OpenApi
Futtassa az alkalmazást, és lépjen a(z) openapi/v1.json
-ra, a létrehozott OpenAPI-dokumentum megtekintéséhez.
Az OpenAPI-dokumentumok buildeléskor is létrehozhatók a Microsoft.Extensions.ApiDescription.Server
csomag hozzáadásával:
dotnet add package Microsoft.Extensions.ApiDescription.Server
A kibocsátott OpenAPI-dokumentumok helyének módosításához állítsa be a cél elérési utat az alkalmazás projektfájljában lévő OpenApiDocumentsDirectory tulajdonságban:
<PropertyGroup>
<OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)</OpenApiDocumentsDirectory>
</PropertyGroup>
Futtassa dotnet build
, és vizsgálja meg a létrehozott JSON-fájlt a projektkönyvtárban.
ASP.NET Core beépített OpenAPI-dokumentumgenerációja számos testreszabási és beállítási lehetőséget támogat. Dokumentum-, művelet- és sématranszformátorokat biztosít, és több OpenAPI-dokumentumot is kezelhet ugyanahhoz az alkalmazáshoz.
Ha többet szeretne megtudni ASP.NET Core új OpenAPI-dokumentum képességeiről, tekintse meg az új Microsoft.AspNetCore.OpenApi dokumentumokat.
A Microsoft.AspNetCore.OpenApi támogatja a vágást és a natív AOT-t
Az OpenAPI a ASP.NET Core-ban támogatja a vágást és a natív AOT-t. Az alábbi lépések egy OpenAPI-alkalmazást hoznak létre és tesznek közzé kódtrimmeléssel és natív AOT használatával:
Hozzon létre egy új ASP.NET Core Web API-projektet (natív AOT-projektet).
dotnet new webapiaot
Adja hozzá a Microsoft.AspNetCore.OpenAPI csomagot.
dotnet add package Microsoft.AspNetCore.OpenApi
Frissítse a(z) Program.cs
elemet az OpenAPI-dokumentumok létrehozásának engedélyezéséhez.
+ builder.Services.AddOpenApi();
var app = builder.Build();
+ app.MapOpenApi();
Tegye közzé az alkalmazást.
dotnet publish
Hitelesítés és engedélyezés
Ez a szakasz a hitelesítés és az engedélyezés új funkcióit ismerteti.
Az OpenIdConnectHandler támogatja a leküldéses engedélyezési kérelmeket (PAR)
Szeretnénk köszönetet mondani Joe DeCockDuende Software-tól, amiért továbbított engedélykérelmeket (PAR) adott hozzá az ASP.NET Core OpenIdConnectHandler-hez. Joe a API-javaslatában a PAR engedélyezésének hátterét és motivációját az alábbiak szerint írta le:
A leküldéses engedélyezési kérelmek (PAR) egy viszonylag új OAuth szabvány, amely javítja az OAuth- és OIDC-folyamatok biztonságát azáltal, hogy az engedélyezési paramétereket az első csatornáról a hátsó csatornára helyezi át. Vagyis az engedélyezési paraméterek áthelyezése a böngészőben lévő átirányítási URL-címekről a háttérrendszeren történő közvetlen gép-gép közötti HTTP-kapcsolatokra.
Ez megakadályozza, hogy egy kibertámadó a böngészőben a következőket tegye:
- Engedélyezési paramétereket lát, amelyek kiszivároghatnak a PII-ből.
- A paraméterek illetéktelen módosítása. A kibertámadás például megváltoztathatja a kért hozzáférés hatókörét.
Az engedélyezési paraméterek átvitele a kérelem URL-címeinek rövidségét is biztosítja. Az engedélyezési paraméterek nagyon hosszú ideig tarthatnak, ha összetettebb OAuth- és OIDC-funkciókat használnak, például Rich Authorization Requests. Azok az URL-címek, amelyek hosszú ideig okoznak problémákat számos böngészőben és hálózati infrastruktúrában.
A PAR használatát az OpenID Foundation
FAPI munkacsoportja támogatja. Például a FAPI2.0 Biztonsági Profil a PAR használatát igényli. Ezt a biztonsági profilt számos olyan csoport használja, amelyek nyílt banki szolgáltatásokon dolgoznak (elsősorban Európában), az egészségügyben és más, magas biztonsági követelményekkel rendelkező iparágakban. A PAR-t számos identitásszolgáltató támogatja, beleértve a
A .NET 9 esetében úgy döntöttünk, hogy alapértelmezés szerint engedélyezi a PAR-t, ha az identitásszolgáltató felderítési dokumentuma támogatja a PAR szolgáltatást, mivel fokozott biztonságot kell nyújtania az azt támogató szolgáltatók számára. Az identitásszolgáltató felderítési dokumentuma általában a következő helyen található: .well-known/openid-configuration
. Ha ez problémákat okoz, a PAR letiltható az alábbiak szerint: OpenIdConnectOptions.PushedAuthorizationBehavior.
builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("oidc", oidcOptions =>
{
// Other provider-specific configuration goes here.
// The default value is PushedAuthorizationBehavior.UseIfAvailable.
// 'OpenIdConnectOptions' does not contain a definition for 'PushedAuthorizationBehavior'
// and no accessible extension method 'PushedAuthorizationBehavior' accepting a first argument
// of type 'OpenIdConnectOptions' could be found
oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Disable;
});
Annak érdekében, hogy a hitelesítés csak PAR használata esetén legyen sikeres, használja PushedAuthorizationBehavior.Require. Ez a módosítás egy új OnPushAuthorization eseményt is bevezet az OpenIdConnectEvents , amely a leküldéses engedélyezési kérelem testreszabására vagy manuális kezelésére használható. További részletekért tekintse meg a API-javaslat.
OIDC és OAuth paraméter testreszabása
Az OAuth- és OIDC-hitelesítési kezelők mostantól AdditionalAuthorizationParameters
beállítással egyszerűbben testre szabhatják azokat az engedélyezési üzenetparamétereket, amelyek általában az átirányítási lekérdezési sztring részeként szerepelnek. A .NET 8-ban és a korábbi verziókban ehhez egyéni OnRedirectToIdentityProvider visszahívásra vagy felülrekedt BuildChallengeUrl metódusra van szükség egy egyéni kezelőben. Íme egy példa a .NET 8-kódra:
builder.Services.AddAuthentication().AddOpenIdConnect(options =>
{
options.Events.OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.SetParameter("prompt", "login");
context.ProtocolMessage.SetParameter("audience", "https://api.example.com");
return Task.CompletedTask;
};
});
Az előző példa mostantól egyszerűsíthető a következő kódra:
builder.Services.AddAuthentication().AddOpenIdConnect(options =>
{
options.AdditionalAuthorizationParameters.Add("prompt", "login");
options.AdditionalAuthorizationParameters.Add("audience", "https://api.example.com");
});
Kiterjesztett hitelesítési jelzők konfigurálása HTTP.sys
Most már konfigurálhatja a HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING
és HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL
HTTP.sys jelzőket a HTTP.sys EnableKerberosCredentialCaching
új CaptureCredentials
és AuthenticationManager tulajdonságaival a Windows-hitelesítés kezelésének optimalizálása érdekében. Például:
webBuilder.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.Negotiate;
options.Authentication.EnableKerberosCredentialCaching = true;
options.Authentication.CaptureCredentials = true;
});
Vegyes
A következő szakaszok a különböző új funkciókat ismertetik.
Új HybridCache
könyvtár
Fontos
A HybridCache
API áthidal néhány rést a meglévő IDistributedCache és IMemoryCache API-kban. Emellett új képességeket is kínál, például:
- "Stampede" védelem, hogy megakadályozza ugyanannak a munkának a párhuzamos lekérését.
- Konfigurálható szerializálás.
A HybridCache
a meglévő IDistributedCache
és IMemoryCache
használat legördülő helyére lett tervezve, és egy egyszerű API-t biztosít az új gyorsítótárazási kód hozzáadásához. Egységes API-t biztosít a folyamatban lévő és a folyamaton kívüli gyorsítótárazáshoz is.
A HybridCache
API leegyszerűsítéséhez hasonlítsa össze a IDistributedCache
használó kóddal. Íme egy példa a IDistributedCache
használatára:
public class SomeService(IDistributedCache cache)
{
public async Task<SomeInformation> GetSomeInformationAsync
(string name, int id, CancellationToken token = default)
{
var key = $"someinfo:{name}:{id}"; // Unique key for this combination.
var bytes = await cache.GetAsync(key, token); // Try to get from cache.
SomeInformation info;
if (bytes is null)
{
// Cache miss; get the data from the real source.
info = await SomeExpensiveOperationAsync(name, id, token);
// Serialize and cache it.
bytes = SomeSerializer.Serialize(info);
await cache.SetAsync(key, bytes, token);
}
else
{
// Cache hit; deserialize it.
info = SomeSerializer.Deserialize<SomeInformation>(bytes);
}
return info;
}
// This is the work we're trying to cache.
private async Task<SomeInformation> SomeExpensiveOperationAsync(string name, int id,
CancellationToken token = default)
{ /* ... */ }
}
Ez sok munka minden alkalommal, beleértve a szerializálást is. A gyorsítótár-kihagyási forgatókönyvben több egyidejű szál is lehet, amelyek mindegyikük cache-hibát szenved el, mindegyikük beolvassa a háttéradatokat, szerializálják őket, majd mindegyikük elküldi az adatokat a gyorsítótárba.
A kód HybridCache
használatával történő egyszerűsítése és fejlesztése érdekében először hozzá kell adnunk az új kódtárat Microsoft.Extensions.Caching.Hybrid
:
<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="9.0.0" />
Regisztrálja a HybridCache
szolgáltatást, mintha egy IDistributedCache
implementációt regisztrálna:
builder.Services.AddHybridCache(); // Not shown: optional configuration API.
Most a legtöbb gyorsítótárazási problémát át lehet helyezni HybridCache
:
public class SomeService(HybridCache cache)
{
public async Task<SomeInformation> GetSomeInformationAsync
(string name, int id, CancellationToken token = default)
{
return await cache.GetOrCreateAsync(
$"someinfo:{name}:{id}", // Unique key for this combination.
async cancel => await SomeExpensiveOperationAsync(name, id, cancel),
token: token
);
}
}
A HybridCache
absztrakt osztály konkrét implementációját függőséginjektálással biztosítjuk, de a fejlesztőknek egyéni implementációkat kell biztosítaniuk az API-hoz. A HybridCache
implementáció a gyorsítótárazással kapcsolatos mindennel foglalkozik, beleértve az egyidejű műveletkezelést is. Az
A nagy átviteli sebességű forgatókönyvek tovább optimalizálhatók a TState
mintával, így elkerülhető a rögzített változók és példányonkénti visszahívások terhelése:
public class SomeService(HybridCache cache)
{
public async Task<SomeInformation> GetSomeInformationAsync(string name, int id, CancellationToken token = default)
{
return await cache.GetOrCreateAsync(
$"someinfo:{name}:{id}", // unique key for this combination
(name, id), // all of the state we need for the final call, if needed
static async (state, token) =>
await SomeExpensiveOperationAsync(state.name, state.id, token),
token: token
);
}
}
HybridCache
a konfigurált IDistributedCache
implementációt használja, ha van ilyen, a másodlagos folyamaton kívüli gyorsítótárazáshoz, például a Redis használatával. De még IDistributedCache
nélkül is a HybridCache
szolgáltatás továbbra is biztosítja a folyamat közbeni gyorsítótárazást és a "túlterhelési" védelmet.
Megjegyzés az objektumok újrafelhasználásával kapcsolatban
A IDistributedCache
használó tipikus meglévő kódban egy objektum gyorsítótárból való minden lekérése deszerializálást eredményez. Ez a viselkedés azt jelenti, hogy minden egyidejű hívó külön példányt kap az objektumból, amely nem tud más példányokkal kommunikálni. Az eredmény a szálbiztonság, mivel nem áll fenn az ugyanazon objektumpéldány egyidejű módosításának kockázata.
Mivel sok HybridCache
használat lesz adaptálva a meglévő IDistributedCache
kódból, HybridCache
alapértelmezés szerint megőrzi ezt a viselkedést az egyidejűségi hibák elkerülése érdekében. Azonban egy bizonyos használati eset eredendően szálbiztos.
- Ha a gyorsítótárazott típusok nem módosíthatók.
- Ha a kód nem módosítja őket.
Ilyen esetekben tájékoztassa HybridCache
, hogy biztonságosan újra felhasználhatja a példányokat a következő módon:
- A
sealed
típus megjelölése. A C#sealed
kulcsszó azt jelenti, hogy az osztály nem örökölhető. - A
[ImmutableObject(true)]
attribútum alkalmazása rá. A[ImmutableObject(true)]
attribútum azt jelzi, hogy az objektum állapota nem módosítható a létrehozása után.
A példányok újrafelhasználásával HybridCache
csökkentheti a hívásonkénti deszerializálással társított processzor- és objektumfoglalások többletterhelését. Ez teljesítménybeli javuláshoz vezethet olyan esetekben, amikor a gyorsítótárazott objektumok nagy méretűek vagy gyakran érhetők el.
Egyéb HybridCache
funkciók
A IDistributedCache
-hez hasonlóan a HybridCache
is támogatja a kulcs szerinti eltávolítást egy RemoveKeyAsync
metódussal.
HybridCache
opcionális API-kat is biztosít IDistributedCache
implementációkhoz a byte[]
lefoglalások elkerülése érdekében. Ezt a funkciót a Microsoft.Extensions.Caching.StackExchangeRedis
és Microsoft.Extensions.Caching.SqlServer
csomagok előzetes verziói implementálják.
A szerializálás a szolgáltatás regisztrálásának részeként van konfigurálva, és támogatja a típusspecifikus és általános szerializálókat a WithSerializer
és .WithSerializerFactory
metódusok segítségével, a AddHybridCache
hívástól láncolt módon. Alapértelmezés szerint a kódtár belsőleg kezeli string
és byte[]
, és minden máshoz System.Text.Json
használ, de használhat protobuf, xml vagy bármi mást.
HybridCache
támogatja a régebbi .NET rendszereket, egészen a .NET Framework 4.7.2-ig és a .NET Standard 2.0-ig.
További információkért a HybridCache
-ról tekintse meg a HybridCache-könyvtárat az ASP.NET Core-ben.
Fejlesztői kivételkezelő oldal fejlesztései
A ASP.NET Core fejlesztői kivétellap jelenik meg, amikor egy alkalmazás kezeletlen kivételt dob a fejlesztés során. A fejlesztői kivételoldal részletes információkat nyújt a kivételről és a kérésről.
A 3. előzetes verzió hozzáadta a végpont metaadatait a fejlesztői kivételoldalhoz. ASP.NET Core végponti metaadatokat használ a végpont viselkedésének szabályozásához, például útválasztás, válasz gyorsítótárazása, sebességkorlátozás, OpenAPI-generálás stb. Az alábbi képen a fejlesztői kivételoldal Routing
szakaszában található új metaadat-információk láthatók:
A fejlesztői kivételoldal tesztelése során a rendszer kis életminőség-javulást észlelt. A 4. előzetes verzióban lettek szállítva:
- Jobb szövegburkolás. A hosszú cookie-k, a lekérdezési sztringértékek és a metódusnevek többé nem adnak hozzá vízszintes böngésző görgetősávokat.
- A modern dizájnokban található nagyobb szöveg.
- Konzisztensebb táblázatméretek.
Az alábbi animált képen az új fejlesztői kivétellap látható:
A szótár hibakeresési fejlesztései
A szótárak és más kulcs-érték gyűjtemények hibakeresési megjelenítése továbbfejlesztett elrendezést biztosít. A kulcs a hibakereső kulcsoszlopában jelenik meg ahelyett, hogy összefűzne az értékkel. Az alábbi képeken egy szótár régi és új megjelenítése látható a hibakeresőben.
Előtt:
Után:
ASP.NET Core számos kulcs-érték gyűjteményből áll. Ez a továbbfejlesztett hibakeresési felület a következőkre vonatkozik:
- HTTP-fejlécek
- Lekérdezési sztringek
- Formák
- Sütik
- Adatok megtekintése
- Útvonal adatok
- Funkciók
A 503-as hibára vonatkozó javítás az IIS-ben történő alkalmazás újraindítása során
Alapértelmezés szerint 1 másodperces késés áll fenn, amikor az IIS értesítést kap az újrahasznosításról vagy a leállításról, és amikor az ANCM arra utasítja a felügyelt kiszolgálót, hogy kezdjen leállni. A késés a ANCM_shutdownDelay
környezeti változóval vagy a shutdownDelay
kezelőbeállításával konfigurálható. Mindkét érték ezredmásodpercben van. A késés elsősorban egy olyan verseny valószínűségének csökkentése, ahol:
- Az IIS nem indította el a sorba állítási kérelmeket az új alkalmazásba való ugráshoz.
- Az ANCM elkezdi elutasítani a régi alkalmazásba érkező új kéréseket.
Előfordulhat, hogy a lassabb gépek vagy a nagyobb processzorhasználattal rendelkező gépek ezt az értéket az 503-ra való valószínűség csökkentése érdekében módosítani szeretnék.
Példa a shutdownDelay
beállítására:
<aspNetCore processPath="dotnet" arguments="myapp.dll" stdoutLogEnabled="false" stdoutLogFile=".logsstdout">
<handlerSettings>
<!-- Milliseconds to delay shutdown by.
this doesn't mean incoming requests will be delayed by this amount,
but the old app instance will start shutting down after this timeout occurs -->
<handlerSetting name="shutdownDelay" value="5000" />
</handlerSettings>
</aspNetCore>
A javítás a globálisan telepített ANCM-modulban található, amely az üzemeltetési csomagból származik.
ASP0026: Az analizátor figyelmeztet, ha az [Authorize] felülbírálva van egy távolabbi [AllowAnonymous] által.
Magától értetődőnek tűnik, hogy egy [Authorize]
attribútum, amely közelebb van egy MVC-művelethez, mint egy [AllowAnonymous]
attribútum, felülírja a [AllowAnonymous]
attribútumot és kényszeríti az engedélyezést. Ez azonban nem feltétlenül igaz. Az attribútumok relatív sorrendje számít.
Az alábbi kód olyan példákat mutat be, ahol egy közelebbi [Authorize]
attribútumot felülír egy távolabbi [AllowAnonymous]
attribútum.
[AllowAnonymous]
public class MyController
{
[Authorize] // Overridden by the [AllowAnonymous] attribute on the class
public IActionResult Private() => null;
}
[AllowAnonymous]
public class MyControllerAnon : ControllerBase
{
}
[Authorize] // Overridden by the [AllowAnonymous] attribute on MyControllerAnon
public class MyControllerInherited : MyControllerAnon
{
}
public class MyControllerInherited2 : MyControllerAnon
{
[Authorize] // Overridden by the [AllowAnonymous] attribute on MyControllerAnon
public IActionResult Private() => null;
}
[AllowAnonymous]
[Authorize] // Overridden by the preceding [AllowAnonymous]
public class MyControllerMultiple : ControllerBase
{
}
A .NET 9 6. előzetes verziójában bevezettünk egy elemzőt, amely az ilyen példányokat emeli ki, ahol egy közelebbi [Authorize]
attribútum felülbírálásra kerül egy MVC-művelettől távolabb eső [AllowAnonymous]
attribútummal. A figyelmeztetés a felülírt [Authorize]
attribútumra mutat az alábbi üzenettel:
ASP0026 [Authorize] overridden by [AllowAnonymous] from farther away
Ha ezt a figyelmeztetést látja, a megfelelő művelet az attribútumok mögötti szándéktól függ. A távolabbi [AllowAnonymous]
attribútumot el kell távolítani, ha véletlenül felfedi a végpontot névtelen felhasználóknak. Ha a [AllowAnonymous]
attribútum egy közelebbi [Authorize]
attribútum felülbírálásához készült, a szándék tisztázásához ismételje meg a [AllowAnonymous]
attribútumot a [Authorize]
attribútum után.
[AllowAnonymous]
public class MyController
{
// This produces no warning because the second, "closer" [AllowAnonymous]
// clarifies that [Authorize] is intentionally overridden.
// Specifying AuthenticationSchemes can still be useful
// for endpoints that allow but don't require authenticated users.
[Authorize(AuthenticationSchemes = "Cookies")]
[AllowAnonymous]
public IActionResult Privacy() => null;
}
Továbbfejlesztett Kestrel kapcsolati metrikák
Jelentősen javítottuk Kestrelkapcsolati metrikáit azáltal, hogy metaadatokat is felveszünk arról, hogy miért hiúsult meg a kapcsolat. A kestrel.connection.duration
metrika mostantól tartalmazza a kapcsolat szoros okát a error.type
attribútumban.
Íme egy kis minta az error.type
értékekből:
-
tls_handshake_failed
– A kapcsolathoz TLS szükséges, és a TLS-kézfogás sikertelen volt. -
connection_reset
– Az ügyfél váratlanul bezárta a kapcsolatot, miközben a kérések folyamatban voltak. -
request_headers_timeout
– Kestrel bezárta a kapcsolatot, mert nem kapott időben kérésfejléceket. -
max_request_body_size_exceeded
– Kestrel lezárta a kapcsolatot, mert a feltöltött adatok mérete meghaladta a maximális méretet.
Korábban a Kestrel kapcsolati problémák diagnosztizálásához a kiszolgálónak részletes, alacsony szintű naplózást kellett rögzítenie. A naplók létrehozása és tárolása azonban költséges lehet, és nehéz lehet megtalálni a megfelelő információkat a zaj között.
A metrikák sokkal olcsóbb alternatívát jelentenek, amelyet minimális hatással lehet folyamatosan működtetni az éles környezetben. Az összegyűjtött metrikák meghajtó irányítópultokat és riasztásokat. Ha a metrikákkal kapcsolatos magas szintű probléma merül fel, a naplózással és más eszközökkel végzett további vizsgálat megkezdődhet.
A továbbfejlesztett kapcsolati metrikák számos esetben hasznosak lehetnek:
- A rövid kapcsolati élettartamok által okozott teljesítményproblémák vizsgálata.
- A teljesítményre és stabilitásra hatással lévő Kestrel elleni folyamatos külső támadások megfigyelése.
- A felvétel olyan külső támadásokat kísérelt meg Kestrel, amelyek Kestrelbeépített biztonsági megkeményedése megakadályozva.
További információ: ASP.NET Alapvető metrikák.
Kestrel nevesített csővégpontok testreszabása
Kestrelnévvel ellátott cső támogatása továbbfejlesztésre került speciális testreszabási lehetőségekkel. A nevesített csőbeállítások új CreateNamedPipeServerStream
metódusa lehetővé teszi a csövek végpontonkénti testreszabását.
Erre példa egy Kestrel alkalmazás, amely két különböző hozzáférési biztonságirendelkező csővégpontot igényel. A CreateNamedPipeServerStream
beállítással a cső nevétől függően egyéni biztonsági beállításokkal rendelkező csövek hozhatók létre.
var builder = WebApplication.CreateBuilder();
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenNamedPipe("pipe1");
options.ListenNamedPipe("pipe2");
});
builder.WebHost.UseNamedPipes(options =>
{
options.CreateNamedPipeServerStream = (context) =>
{
var pipeSecurity = CreatePipeSecurity(context.NamedPipeEndpoint.PipeName);
return NamedPipeServerStreamAcl.Create(context.NamedPipeEndPoint.PipeName, PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte,
context.PipeOptions, inBufferSize: 0, outBufferSize: 0, pipeSecurity);
};
});
ExceptionHandlerMiddleware
lehetőség az állapotkód kivételtípus alapján történő kiválasztására
A ExceptionHandlerMiddleware
konfigurálásakor egy új lehetőség lehetővé teszi, hogy az alkalmazásfejlesztők kiválasztják, milyen állapotkódot adjanak vissza, amikor kivétel történik a kérések kezelése során. Az új beállítás módosítja a ProblemDetails
ExceptionHandlerMiddleware
válaszában beállított állapotkódot.
app.UseExceptionHandler(new ExceptionHandlerOptions
{
StatusCodeSelector = ex => ex is TimeoutException
? StatusCodes.Status503ServiceUnavailable
: StatusCodes.Status500InternalServerError,
});
HTTP-metrikák letiltása bizonyos végpontokon és kéréseken
A .NET 9 lehetővé teszi a HTTP-metrikák letiltását adott végpontok és kérések esetében. A metrikák rögzítésének letiltása előnyös az automatizált rendszerek által gyakran hívott végpontok, például az állapot-ellenőrzések esetében. Ezeknek a kéréseknek a metrikáinak rögzítése általában szükségtelen.
A végpontra irányuló HTTP-kérések metaadatok hozzáadásával kizárhatók a metrikákból. Vagy:
- Adja hozzá a
[DisableHttpMetrics]
attribútumot a webes API-vezérlőhöz, SignalR központhoz vagy gRPC szolgáltatáshoz. - Hívás DisableHttpMetrics az alkalmazás indításakor a végpontok leképezésekor:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/healthz").DisableHttpMetrics();
app.Run();
A MetricsDisabled
tulajdonság hozzá lett adva a következőhöz: IHttpMetricsTagsFeature
.
- Speciális forgatókönyvek, ahol a kérések nem vezetnek végponthoz.
- A metrikák gyűjteményének dinamikus letiltása adott HTTP-kérésekhez.
// Middleware that conditionally opts-out HTTP requests.
app.Use(async (context, next) =>
{
var metricsFeature = context.Features.Get<IHttpMetricsTagsFeature>();
if (metricsFeature != null &&
context.Request.Headers.ContainsKey("x-disable-metrics"))
{
metricsFeature.MetricsDisabled = true;
}
await next(context);
});
Adatvédelmi támogatás kulcsok törléséhez
A .NET 9-et megelőzően az adatvédelmi kulcsok nem törölhetők a terv szerint, hogy megelőzzék az adatvesztést. A kulcs törlése visszavonhatatlanná teszi a védett adatokat. Kis méretük miatt ezeknek a kulcsoknak a felhalmozódása általában minimális hatást gyakorolt. A rendkívül hosszú ideig futó szolgáltatások fogadására azonban bevezettük a kulcsok törlésének lehetőségét. Általában csak a régi kulcsokat kell törölni. Csak akkor törölje a kulcsokat, ha el tudja fogadni az adatvesztés kockázatát a tárolási megtakarításokért cserébe. Javasoljuk, hogy ne törölje az adatvédelmi kulcsokat.
using Microsoft.AspNetCore.DataProtection.KeyManagement;
var services = new ServiceCollection();
services.AddDataProtection();
var serviceProvider = services.BuildServiceProvider();
var keyManager = serviceProvider.GetService<IKeyManager>();
if (keyManager is IDeletableKeyManager deletableKeyManager)
{
var utcNow = DateTimeOffset.UtcNow;
var yearAgo = utcNow.AddYears(-1);
if (!deletableKeyManager.DeleteKeys(key => key.ExpirationDate < yearAgo))
{
Console.WriteLine("Failed to delete keys.");
}
else
{
Console.WriteLine("Old keys deleted successfully.");
}
}
else
{
Console.WriteLine("Key manager does not support deletion.");
}
A köztes szoftver támogatja a keyed DI-t
A Middleware mostantól a konstruktorban és a Invoke
/ metódusban is támogatja a InvokeAsync
.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKeyedSingleton<MySingletonClass>("test");
builder.Services.AddKeyedScoped<MyScopedClass>("test2");
var app = builder.Build();
app.UseMiddleware<MyMiddleware>();
app.Run();
internal class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next,
[FromKeyedServices("test")] MySingletonClass service)
{
_next = next;
}
public Task Invoke(HttpContext context,
[FromKeyedServices("test2")]
MyScopedClass scopedService) => _next(context);
}
Bízzon az ASP.NET Core HTTPS fejlesztői tanúsítványban Linuxon
Az Ubuntu- és Fedora-alapú Linux-disztribúciókon dotnet dev-certs https --trust
mostantól megbízható tanúsítványként konfigurálja ASP.NET Core HTTPS fejlesztési tanúsítványt a következőkhöz:
- Chromium böngészők, például Google Chrome, Microsoft Edge és Chromium.
- Mozilla Firefox és Mozilla származtatott böngészők.
- .NET API-k, például HttpClient
Korábban --trust
csak Windows és macOS rendszeren működött. A rendszer felhasználónként alkalmazza a tanúsítványmegbízhatóságot.
Az OpenSSL-ben való bizalom kialakításához az dev-certs
eszköz:
- A tanúsítványt a
~/.aspnet/dev-certs/trust
-ba helyezi - Az OpenSSL c_rehash eszközének egyszerűsített verzióját futtatja a címtárban.
- Felkéri a felhasználót, hogy frissítse a
SSL_CERT_DIR
környezeti változót.
A dotnetbe vetett bizalom létrehozásához az eszköz a tanúsítványt a My/Root
tanúsítványtárolóba helyezi.
Az NSS-adatbázisokmegbízhatóságának kialakításához, ha van ilyen, az eszköz megkeresi a saját könyvtárban a Firefox-profilokat, ~/.pki/nssdb
és ~/snap/chromium/current/.pki/nssdb
. Az eszköz minden talált könyvtárhoz hozzáad egy bejegyzést a nssdb
-ba.
A legújabb Bootstrap-, jQuery- és jQuery-érvényesítési verziókra frissített sablonok
A ASP.NET Core-projektsablonok és -kódtárak a Bootstrap, a jQuery és a jQuery Validation legújabb verzióinak használatára lettek frissítve, különösen a következőkkel:
- Bootstrap 5.3.3
- jQuery 3.7.1
- jQuery validation 1.21.0