ASP.NET Core 9.0'daki yenilikler
Bu makalede, ASP.NET Core 9.0'daki en önemli değişiklikler ilgili belgelerin bağlantıları ile vurgulanır.
Bu makale .NET 9 Sürüm Adayı 2 için güncelleştirildi.
Blazor
Bu bölümde için Blazoryeni özellikler açıklanmaktadır.
.NET MAUIBlazor Hybrid ve Web App çözüm şablonu
Yeni bir çözüm şablonu, aynı kullanıcı arabirimini paylaşan yerel ve Blazor web istemcisi uygulamaları oluşturmayı .NET MAUI kolaylaştırır. Bu şablonda kodun yeniden kullanılmasını en üst düzeye çıkaran ve Android, iOS, Mac, Windows ve Web'i hedefleyen istemci uygulamalarının nasıl oluşturulacağı gösterilmektedir.
Bu şablonun temel özellikleri şunlardır:
- Web uygulaması için etkileşimli bir Blazor işleme modu seçme özelliği.
- Bir (genel Etkileşimli Otomatik işleme) ve bir uygulama da dahil olmak üzere Blazor Web App uygun projelerin otomatik oluşturulması .NET MAUIBlazor Hybrid .
- Oluşturulan projeler, kullanıcı arabiriminin Razor bileşenlerini korumak için paylaşılan Razor bir sınıf kitaplığı (RCL) kullanır.
- Uygulama ve için farklı arabirim uygulamaları sağlamak üzere bağımlılık eklemenin Blazor Hybrid nasıl kullanılacağını gösteren örnek kod eklenmiştir Blazor Web App.
Başlamak için .NET 9 SDK'sını .NET MAUI yükleyin ve şablonu içeren iş yükünü yükleyin:
dotnet workload install maui
Aşağıdaki komutu kullanarak komut kabuğunda proje şablonundan bir çözüm oluşturun:
dotnet new maui-blazor-web
Şablon Visual Studio'da da kullanılabilir.
Not
Şu anda, işleme modları sayfa başına/bileşen düzeyinde tanımlanmışsa Blazor bir özel durum oluşur. Daha fazla bilgi için bkz . BlazorWebView, ResolveComponentForRenderMode (dotnet/aspnetcore
#51235) geçersiz kılmayı etkinleştirmek için bir yönteme ihtiyaç duyar.
Daha fazla bilgi için bkz. ile Blazor Web Appuygulama oluşturma.NET MAUIBlazor Hybrid.
Statik varlık teslim iyileştirmesi
MapStaticAssets
uygulamalar da dahil olmak üzere Blazor tüm ASP.NET Core uygulamalarında statik varlıkların teslimini iyileştirmeye yardımcı olan yeni bir ara yazılımdır.
Daha fazla bilgi için aşağıdaki kaynaklardan birini inceleyin:
- Bu makalenin Statik web varlığı teslimini iyileştirme bölümü.
- ASP.NET Core Blazor statik dosyaları.
Çalışma zamanında işleme konumunu, etkileşimini ve atanan işleme modunu algılama
Çalışma zamanında bileşen durumlarını sorgulama işlemini basitleştirmek için tasarlanmış yeni bir API kullanıma sunulmuştur. Bu API aşağıdaki özellikleri sağlar:
- Bileşenin geçerli yürütme konumunu belirleyin: Bu özellikle hata ayıklama ve bileşen performansını iyileştirme için yararlı olabilir.
- Bileşenin etkileşimli bir ortamda çalışıp çalışmadığını denetleyin: Bu, ortamlarının etkileşimi temelinde farklı davranışlara sahip bileşenler için yararlı olabilir.
- Bileşen için atanan işleme modunu alma: İşleme modunu anlamak, işleme işlemini iyileştirmeye ve bir bileşenin genel performansını iyileştirmeye yardımcı olabilir.
Daha fazla bilgi için bkz . ASP.NET Core Blazor işleme modları.
Geliştirilmiş sunucu tarafı yeniden bağlantı deneyimi:
Varsayılan sunucu tarafı yeniden bağlantı deneyiminde aşağıdaki geliştirmeler yapılmıştır:
Kullanıcı bağlantısı kesilmiş bir uygulamaya geri döndüğünde, bir sonraki yeniden bağlantı aralığının süresini beklemek yerine hemen yeniden bağlanma denenir. Bu, uyku moduna geçmiş bir tarayıcı sekmesindeki bir uygulamaya gidildiğinde kullanıcı deneyimini geliştirir.
Yeniden bağlanma girişimi sunucuya ulaştığında ancak sunucu devreyi zaten serbest bıraktığında, otomatik olarak bir sayfa yenilemesi gerçekleşir. Bu, büyük olasılıkla yeniden bağlantının başarılı olmasına neden olacaksa kullanıcının sayfayı el ile yenilemesini önler.
Yeniden bağlanma zamanlaması hesaplanan geri alma stratejisini kullanır. Varsayılan olarak, ilk birkaç yeniden bağlantı girişimi, denemeler arasında hesaplanan gecikmeler ortaya çıkmadan önce yeniden deneme aralığı olmadan hızlı bir şekilde gerçekleşir. Aşağıdaki üstel geri alma örneğinde gösterildiği gibi yeniden deneme aralığını hesaplamak için bir işlev belirterek yeniden deneme aralığı davranışını özelleştirebilirsiniz:
Blazor.start({ circuit: { reconnectionOptions: { retryIntervalMilliseconds: (previousAttempts, maxRetries) => previousAttempts >= maxRetries ? null : previousAttempts * 1000 }, }, });
Varsayılan yeniden bağlantı kullanıcı arabiriminin stili modernleştirildi.
Daha fazla bilgi için bkz . ASP.NET Temel BlazorSignalR kılavuzu.
s için Blazor Web Appbasitleştirilmiş kimlik doğrulama durumu serileştirmesi
Yeni API'ler, mevcut Blazor Web Appbir öğesine kimlik doğrulaması eklemeyi kolaylaştırır. Tek Tek Hesapları kullanarak kimlik doğrulamasıyla yeni Blazor Web App bir hesap oluşturduğunuzda ve WebAssembly tabanlı etkileşimi etkinleştirdiğinizde, proje hem sunucu hem de istemci projelerinde bir özel AuthenticationStateProvider içerir.
Bu sağlayıcılar kullanıcının kimlik doğrulama durumunu tarayıcıya akıtıyor. İstemci yerine sunucuda kimlik doğrulaması, uygulamanın ön kayıt sırasında ve .NET WebAssembly çalışma zamanı başlatılmadan önce kimlik doğrulama durumuna erişmesine olanak tanır.
Özel AuthenticationStateProvider uygulamalar, kimlik doğrulama durumunu HTML açıklamalarına seri hale getirmek ve yeni AuthenticationState bir örnek oluşturmak için WebAssembly'den geri okumak için Kalıcı Bileşen Durumu hizmetini (PersistentComponentState) kullanır.
Proje şablonundan Blazor Web App başlayıp Tek Tek Hesaplar seçeneğini belirlediyseniz ancak mevcut bir projeye kimlik doğrulaması eklemeye çalışıyorsanız kendinizi uygulamak veya kopyalamak için çok fazla kod kullanabilirsiniz. Artık proje şablonunun parçası Blazor Web App olan ve bu işlevselliği eklemek için sunucu ve istemci projelerinde çağrılabilen API'ler vardır:
AddAuthenticationStateSerialization
: Sunucudaki kimlik doğrulama durumunu seri hale getirmek için gerekli hizmetleri ekler.AddAuthenticationStateDeserialization
: Tarayıcıda kimlik doğrulama durumunu seri durumdan çıkarmak için gerekli hizmetleri ekler.
Varsayılan olarak, API yalnızca tarayıcıdaki erişim için sunucu tarafı adını ve rol taleplerini serileştirir. Tüm talepleri dahil etmek için seçeneği AddAuthenticationStateSerialization
geçirilebilir.
Daha fazla bilgi için, Güvenli ASP.NET Core sunucu tarafı Blazor uygulamalarının aşağıdaki bölümlerine bakın:
- BlazorIdentity Kullanıcı Arabirimi (Bireysel Hesaplar)
- s içinde Blazor Web Appkimlik doğrulama durumunu yönetme
Genel olarak etkileşimli bir sayfaya statik sunucu tarafı işleme (SSR) sayfaları ekleme Blazor Web App
.NET 9 sürümüyle, genel etkileşimi benimseyen uygulamalara statik SSR sayfaları eklemek artık daha kolay.
Bu yaklaşım yalnızca uygulamanın etkileşimli Sunucu veya WebAssembly işleme ile çalışamaz belirli sayfaları olduğunda yararlıdır. Örneğin, okuma/yazma HTTP tanımlama bilgilerine bağımlı olan ve etkileşimli işleme yerine yalnızca istek/yanıt döngüsünde çalışabilen sayfalar için bu yaklaşımı benimseyin. Etkileşimli işleme ile çalışan sayfalar için, son kullanıcı için daha az verimli ve daha az yanıt veren olduğundan, bunları statik SSR işleme kullanmaya zorlamamalısınız.
Herhangi bir Razor bileşen sayfasını yönergesiyle atanan yeni [ExcludeFromInteractiveRouting]
öznitelikle @attribute
Razor işaretleyin:
@attribute [ExcludeFromInteractiveRouting]
özniteliğinin uygulanması, sayfada gezintinin etkileşimli yönlendirmeden çıkmasına neden olur. Gelen gezinti, etkileşimli yönlendirme yoluyla sayfayı çözümlemek yerine tam sayfa yeniden yükleme gerçekleştirmeye zorlanır. Tam sayfa yeniden yükleme, genellikle App
bileşeni ()App.razor
olan üst düzey kök bileşeni sunucudan yeniden yüklemeye zorlayarak uygulamanın farklı bir üst düzey işleme moduna geçmesini sağlar.
HttpContext.AcceptsInteractiveRouting
Uzantı yöntemi, bileşenin geçerli sayfaya uygulanıp uygulanmadığını [ExcludeFromInteractiveRouting]
algılamasına olanak tanır.
Bileşeninde App
, aşağıdaki örnekteki deseni kullanın:
- Genel etkileşime sahip
[ExcludeFromInteractiveRouting]
işleme moduna varsayılanInteractiveServer
olarak ek açıklama eklenmemiş sayfalar. veya ileInteractiveWebAssembly
InteractiveAuto
değiştirerekInteractiveServer
farklı bir varsayılan genel işleme modu belirtebilirsiniz. - Statik SSR'yi benimseme ile
[ExcludeFromInteractiveRouting]
ek açıklamalı sayfalar (PageRenderMode
atanırnull
).
<!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;
}
Uzantı yöntemini kullanmanın HttpContext.AcceptsInteractiveRouting
bir alternatifi, kullanarak HttpContext.GetEndpoint()?.Metadata
uç nokta meta verilerini el ile okumaktır.
Bu özellik, ASP.NET Core Blazor işleme modlarındaki başvuru belgeleri kapsamındadır.
Oluşturucu ekleme
Razor bileşenler oluşturucu eklemeyi destekler.
Aşağıdaki örnekte, kısmi (arka planda kod) sınıfı birincil oluşturucu kullanarak hizmeti ekliyorNavigationManager
:
public partial class ConstructorInjection(NavigationManager navigation)
{
private void HandleClick()
{
navigation.NavigateTo("/counter");
}
}
Daha fazla bilgi için bkz . ASP.NET Core Blazor bağımlılık ekleme.
Etkileşimli Sunucu bileşenleri için Websocket sıkıştırması
Varsayılan olarak, Etkileşimli Sunucu bileşenleri WebSocket bağlantıları için sıkıştırmayı etkinleştirir ve yalnızca sıkıştırma etkinleştirildiğinde veya WebSocket bağlamı için bir frame-ancestors
yapılandırma sağlandığında uygulamanın hizmet verildiği kaynaktan birinde <iframe>
eklemeye izin veren bir İçerik Güvenlik İlkesi (CSP) yönergesi olarak ayarlanır'self'
.
Sıkıştırma ayarı olarak devre dışı bırakılabilir ConfigureWebSocketOptions
null
ve bu da uygulamanın saldırıyla ilgili güvenlik açığını azaltır ancak performansın düşmesine neden olabilir:
.AddInteractiveServerRenderMode(o => o.ConfigureWebSocketOptions = null)
WebSocket sıkıştırmasına izin veren ancak tarayıcıların uygulamayı herhangi <iframe>
bir içine eklemesini engelleyen (tek tırnak gereklidir) değeriyle 'none'
daha frame-ancestors
katı bir CSP yapılandırın:
.AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = "'none'")
Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:
- ASP.NET Temel BlazorSignalR kılavuzu
- ASP.NET Core Blazor etkileşimli sunucu tarafı işleme için tehdit azaltma kılavuzu
uygulamasında klavye oluşturma olaylarını işleme Blazor
Yeni KeyboardEventArgs.IsComposing
özellik, klavye olayının bir oluşturma oturumunun parçası olup olmadığını gösterir. Klavye olaylarının oluşturma durumunu izlemek, uluslararası karakter giriş yöntemlerini işlemek için çok önemlidir.
QuickGrid
özelliğine OverscanCount
parametresi eklendi
QuickGrid
Bileşen artık sanallaştırma etkinleştirildiğinde görünür bölgeden önce ve sonra kaç ek satırın işlendiğini belirten bir OverscanCount
özellik kullanıma sunar.
Varsayılan OverscanCount
değer 3'dür. Aşağıdaki örnek değerini 4'e OverscanCount
yükseltir:
<QuickGrid ItemsProvider="itemsProvider" Virtualize="true" OverscanCount="4">
...
</QuickGrid>
InputNumber
bileşeni özniteliğini type="range"
destekler
Bileşen InputNumber<TValue> artık model bağlamayı ve form doğrulamayı type="range"
destekleyen bir aralık girişi oluşturan ve genellikle metin kutusu yerine kaydırıcı veya arama denetimi olarak işlenen özniteliğini destekler:
<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; }
}
}
Sunucu projesi başına birden çok Blazor Web Appsn
.NET 10 (Kasım 2025) için sunucu başına birden çok Blazor Web Appproje desteği dikkate alınacaktır.
Daha fazla bilgi için bkz . Sunucu projesi başına birden çok Blazor Web uygulaması desteği (dotnet/aspnetcore
#52216).
SignalR
Bu bölümde için SignalRyeni özellikler açıklanmaktadır.
Hub'larda SignalR polimorfik tür desteği
Hub yöntemleri artık çok biçimli senaryoları etkinleştirmek için türetilmiş sınıf yerine bir temel sınıfı kabul edebilir. Çok biçimliliğe izin vermek için taban türüne açıklama eklenmelidir.
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; }
}
için Geliştirilmiş Etkinlikler SignalR
SignalR şimdi hub yöntemi çağrıları için olayları yayan adlı Microsoft.AspNetCore.SignalR.Server
bir ActivitySource'a sahip:
- Her yöntem kendi etkinliğidir, bu nedenle hub yöntemi çağrısı sırasında bir etkinlik yayan her şey hub yöntemi etkinliğinin altındadır.
- Hub yöntemi etkinliklerinin üst öğesi yoktur. Bu, uzun süre çalışan SignalR bağlantı altında paketlenmedikleri anlamına gelir.
Aşağıdaki örnekte pano ve OpenTelemetry paketleri kullanılır.NET Aspire:
<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" />
Dosyaya aşağıdaki başlangıç kodunu Program.cs
ekleyin:
// 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())
{
// We want to view all traces in development
tracing.SetSampler(new AlwaysOnSampler());
}
tracing.AddAspNetCoreInstrumentation();
tracing.AddSource("Microsoft.AspNetCore.SignalR.Server");
});
builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => tracing.AddOtlpExporter());
Aşağıda Aspire Panosu'ndan alınan örnek çıkış verilmiştir:
SignalR kırpmayı ve Yerel AOT'yi destekler
.NET 8'de başlayan Yerel AOT yolculuğuna devam edersek, hem istemci hem de SignalR sunucu senaryoları için kırpmayı ve yerel önceden (AOT) derleme desteğini etkinleştirdik. Artık gerçek zamanlı web iletişimleri için kullanılan uygulamalarda Yerel AOT kullanmanın SignalR performans avantajlarından yararlanabilirsiniz.
Başlarken
En son .NET 9 SDK'sını yükleyin.
Aşağıdaki komutu kullanarak komut kabuğundaki şablondan webapiaot
bir çözüm oluşturun:
dotnet new webapiaot -o SignalRChatAOTExample
Dosyanın içeriğini Program.cs
aşağıdaki SignalR kodla değiştirin:
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);
}
}
Yukarıdaki örnek, 10 MB'lık yerel bir Windows yürütülebilir dosyası ve 10,9 MB Linux yürütülebilir dosyası oluşturur.
Sınırlamalar
- Şu anda yalnızca JSON protokolü desteklenmektedir:
- Önceki kodda gösterildiği gibi, JSON serileştirme ve Yerel AOT kullanan uygulamaların Kaynak Oluşturucu'ya sahip
System.Text.Json
olması gerekir. - Bu, minimum API'ler ile aynı yaklaşımı izler.
- Önceki kodda gösterildiği gibi, JSON serileştirme ve Yerel AOT kullanan uygulamaların Kaynak Oluşturucu'ya sahip
- SignalR Sunucuda, valueType () türünde
IAsyncEnumerable<T>
veChannelReader<T>
burada bir ValueType (struct
) olanT
Hub yöntemi parametreleri desteklenmez. Bu türlerin kullanılması, geliştirme aşamasında ve yayımlanan uygulamada başlangıçta bir çalışma zamanı özel durumuyla sonuçlanır. Daha fazla bilgi için bkz SignalR. Yerel AOT'de ValueTypes ile IAsyncEnumerable<T> ve ChannelReader<T> Kullanma (dotnet/aspnetcore
#56179). - Yerel AOT (
PublishAot
) ile kesin türemiş hub'lar desteklenmez. Yerel AOT ile kesin olarak yazılan hub'ların kullanılması derleme ve yayımlama sırasında uyarılarla ve çalışma zamanı özel durumuyla sonuçlanır. Kesin olarak belirlenmiş hub'ların kırpma (PublishedTrimmed
) ile kullanılması desteklenir. - Yalnızca
Task
,Task<T>
,ValueTask
veyaValueTask<T>
zaman uyumsuz dönüş türleri için desteklenir.
Minimal API'ler
Bu bölümde en düşük API'lere yönelik yeni özellikler açıklanmaktadır.
ve InternalServerError<TValue>
eklendi InternalServerError
TypedResults
sınıfı TypedResults , minimum API'den kesin olarak türlenmiş HTTP durum kodu tabanlı yanıtlar döndürmek için yararlı bir araçtır. TypedResults
artık uç noktalardan "500 İç Sunucu Hatası" yanıtı döndürmek için fabrika yöntemlerini ve türlerini içerir. Aşağıda 500 yanıt döndüren bir örnek verilmişti:
var app = WebApplication.Create();
app.MapGet("/", () => TypedResults.InternalServerError("Something went wrong!"));
app.Run();
Arama ProducesProblem
ve ProducesValidationProblem
rota gruplarında
ProducesProblem
ve ProducesValidationProblem
uzantı yöntemleri, yol gruplarında kullanımını destekleyecek şekilde güncelleştirildi. Bu yöntemler, bir yol grubundaki tüm uç noktaların OpenAPI meta verilerinin amaçları doğrultusunda döndürebileceğini ProblemDetails
veya ValidationProblemDetails
yanıt verebileceğini gösterir.
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);
OpenAPI
Bu bölümde OpenAPI'nin yeni özellikleri açıklanmaktadır
OpenAPI belge oluşturma için yerleşik destek
OpenAPI belirtimi, HTTP API'lerini açıklamaya yönelik bir standarttır. Standart, geliştiricilerin istemci oluşturucularına, sunucu oluşturucularına, test araçlarına, belgelere ve daha fazlasına takılabilen API'lerin şeklini tanımlamasına olanak tanır. .NET 9 Preview'da ASP.NET Core, Microsoft.AspNetCore.OpenApi paketi aracılığıyla denetleyici tabanlı veya en düşük API'leri temsil eden OpenAPI belgeleri oluşturmak için yerleşik destek sağlar.
Aşağıdaki vurgulanmış kod çağrıları:
AddOpenApi
uygulamasının DI kapsayıcısına gerekli bağımlılıkları kaydetmek için.MapOpenApi
uygulamasının yollarına gerekli OpenAPI uç noktalarını kaydetmek için.
var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.MapGet("/hello/{name}", (string name) => $"Hello {name}"!);
app.Run();
Microsoft.AspNetCore.OpenApi
Aşağıdaki komutu kullanarak paketi projeye yükleyin:
dotnet add package Microsoft.AspNetCore.OpenApi --prerelease
Uygulamayı çalıştırın ve oluşturulan OpenAPI belgesini görüntülemek için adresine gidin openapi/v1.json
:
OpenAPI belgeleri, paket eklenerek Microsoft.Extensions.ApiDescription.Server
derleme zamanında da oluşturulabilir:
dotnet add package Microsoft.Extensions.ApiDescription.Server --prerelease
Uygulamanın proje dosyasına aşağıdakileri ekleyin:
<PropertyGroup>
<OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)</OpenApiDocumentsDirectory>
<OpenApiGenerateDocuments>true</OpenApiGenerateDocuments>
</PropertyGroup>
Proje dizininde oluşturulan JSON dosyasını çalıştırın dotnet build
ve inceleyin.
ASP.NET Core'un yerleşik OpenAPI belge oluşturma işlemi, çeşitli özelleştirmeler ve seçenekler için destek sağlar. Belge ve işlem transformatörleri sağlar ve aynı uygulama için birden çok OpenAPI belgesini yönetme özelliğine sahiptir.
ASP.NET Core'un yeni OpenAPI belge özellikleri hakkında daha fazla bilgi edinmek için yeni Microsoft.AspNetCore.OpenApi belgelerine bakın.
OpenAPI paketi için Intellisense tamamlama geliştirmeleri
ASP.NET Core'un OpenAPI desteği artık daha erişilebilir ve kullanıcı dostudur. OpenAPI API'leri, paylaşılan çerçeveden ayrı olarak bağımsız bir paket olarak gönderilir. Şimdiye kadar bu, geliştiricilerin OpenAPI API'leri için IntelliSense gibi kod tamamlama özelliklerine uygun olmadığı anlamına geliyordu.
Bu boşluğu fark ederek yeni bir tamamlama sağlayıcısı ve kod düzelticisi kullanıma sunulmuştur. Bu araçlar OpenAPI API'lerinin bulunmasını ve kullanımını kolaylaştıracak şekilde tasarlanmıştır ve geliştiricilerin OpenAPI'yi projeleriyle tümleştirmesini kolaylaştırır. Tamamlama sağlayıcısı gerçek zamanlı kod önerileri sunarken, kod düzeltici yaygın hataları düzeltmeye ve API kullanımını iyileştirmeye yardımcı olur. Bu geliştirme, geliştirici deneyimini iyileştirmeye ve API ile ilgili iş akışlarını kolaylaştırmaya yönelik sürekli taahhüdümüzün bir parçasıdır.
Kullanıcı OpenAPI ile ilgili API'nin kullanılabildiği bir deyim yazdığınızda, tamamlama sağlayıcısı API için bir öneri görüntüler. Örneğin, aşağıdaki ekran görüntülerinde, kullanıcı IEndpointConventionBuilder gibi desteklenen bir türde bir çağırma deyimi girerken AddOpenApi ve MapOpenApi tamamlamaları sağlanır:
Tamamlama kabul edildiğinde ve Microsoft.AspNetCore.OpenApi
paket yüklenmediğinde, kod düzeltici, projeye bağımlılığı otomatik olarak yüklemek için bir kısayol sağlar.
Parametreler ve özelliklerde ve [DefaultValue]
öznitelikleri için [Required]
destek
[Required]
Karmaşık türlerdeki parametrelere veya özelliklere ve [DefaultValue]
öznitelikleri uygulandığında, OpenAPI uygulaması bunları required
parametre veya tür şemasıyla ilişkili OpenAPI belgesindeki ve default
özellikleriyle eşler.
Örneğin, aşağıdaki API türü için eşlik eden şemayı Todo
oluşturur.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.MapPost("/todos", (Todo todo) => { });
app.Run();
class Todo
{
public int Id { get; init; }
public required string Title { get; init; }
[DefaultValue("A new todo")]
public required string Description { get; init; }
[Required]
public DateTime CreatedOn { get; init; }
}
{
"required": [
"title",
"description",
"createdOn"
],
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"title": {
"type": "string"
},
"description": {
"type": "string",
"default": "A new todo"
},
"createdOn": {
"type": "string",
"format": "date-time"
}
}
}
OpenAPI belgelerinde şema dönüştürücüleri desteği
Yerleşik OpenAPI desteği artık System.Text.Json ve OpenAPI uygulaması tarafından oluşturulan şemaları değiştirmek için kullanılabilecek şema dönüştürücüleri desteğiyle birlikte gelir. Belge ve işlem transformatörleri gibi şema transformatörleri de OpenApiOptions nesnesine kaydedilebilir. Örneğin, aşağıdaki kod örneği, bir türün şemasına örnek eklemek için şema dönüştürücüsunun kullanılmasını gösterir.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Microsoft.OpenApi.Any;
var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi(options =>
{
options.AddSchemaTransformer((schema, context, cancellationToken) =>
{
if (context.JsonTypeInfo.Type == typeof(Todo))
{
schema.Example = new OpenApiObject
{
["id"] = new OpenApiInteger(1),
["title"] = new OpenApiString("A short title"),
["description"] = new OpenApiString("A long description"),
["createdOn"] = new OpenApiDateTime(DateTime.Now)
};
}
return Task.CompletedTask;
});
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.MapPost("/todos", (Todo todo) => { });
app.Run();
class Todo
{
public int Id { get; init; }
public required string Title { get; init; }
[DefaultValue("A new todo")]
public required string Description { get; init; }
[Required]
public DateTime CreatedOn { get; init; }
}
Microsoft.AspNetCore.OpenApi'de transformatör kayıt API'lerinde iyileştirmeler
OpenAPI transformatörleri OpenAPI belgesini, belge içindeki işlemleri veya API'deki türlerle ilişkili şemaları değiştirmeyi destekler. Transformatörleri OpenAPI belgesine kaydetmeye yönelik API'ler, transformatörleri kaydetmek için çeşitli seçenekler sağlar.
Daha önce transformatörleri kaydetmek için aşağıdaki API'ler kullanılabilirdi:
OpenApiOptions AddDocumentTransformer(Func<OpenApiDocument, OpenApiDocumentTransformerContext, CancellationToken, Task> transformer)
OpenApiOptions AddDocumentTransformer(IOpenApiDocumentTransformer transformer)
OpenApiOptions AddDocumentTransformer<IOpenApiDocumentTransformer>()
OpenApiOptions UseSchemaTransformer(Func<OpenApiSchema, OpenApiSchemaTransformerContext, CancellationToken, Task>)
OpenApiOptions AddOperationTransformer(Func<OpenApiOperation, OpenApiOperationTransformerContext, CancellationToken, Task>)
Yeni API kümesi aşağıdaki gibidir:
OpenApiOptions AddDocumentTransformer(Func<OpenApiDocument, OpenApiDocumentTransformerContext, CancellationToken, Task> transformer)
OpenApiOptions AddDocumentTransformer(IOpenApiDocumentTransformer transformer)
OpenApiOptions AddDocumentTransformer<IOpenApiDocumentTransformer>()
OpenApiOptions AddSchemaTransformer(Func<OpenApiSchema, OpenApiSchemaTransformerContext, CancellationToken, Task> transformer)
OpenApiOptions AddSchemaTransformer(IOpenApiSchemaTransformer transformer)
OpenApiOptions AddSchemaTransformer<IOpenApiSchemaTransformer>()
OpenApiOptions AddOperationTransformer(Func<OpenApiOperation, OpenApiOperationTransformerContext, CancellationToken, Task> transformer)
OpenApiOptions AddOperationTransformer(IOpenApiOperationTransformer transformer)
OpenApiOptions AddOperationTransformer<IOpenApiOperationTransformer>()
Microsoft.AspNetCore.OpenApi kırpmayı ve Yerel AOT'yi destekler
ASP.NET Core'daki yeni yerleşik OpenAPI desteği artık kırpmayı ve Yerel AOT'yi de destekliyor.
Kullanmaya başlayın
Yeni bir ASP.NET Core Web API (Yerel AOT) projesi oluşturun.
dotnet new webapiaot
Microsoft.AspNetCore.OpenAPI paketini ekleyin.
dotnet add package Microsoft.AspNetCore.OpenApi --prerelease
Bu önizlemede, kırpma uyarılarını önlemek için en son Microsoft.OpenAPI paketini de eklemeniz gerekir.
dotnet add package Microsoft.OpenApi
OpenAPI belgeleri oluşturmayı etkinleştirmek için Program.cs güncelleştirin.
+ builder.Services.AddOpenApi();
var app = builder.Build();
+ app.MapOpenApi();
Uygulamayı yayımlayın.
dotnet publish
Uygulama, uyarı olmadan Yerel AOT kullanarak yayımlar.
Arama ve ProducesValidationProblem
rota gruplarında destek ProducesProblem
ProducesProblem ve ProducesValidationProblem uzantısı yöntemleri, yol grupları için güncelleştirildi. Bu yöntemler, bir yol grubundaki tüm uç noktaların OpenAPI meta verilerinin amaçları doğrultusunda döndürebileceğini ProblemDetails
veya ValidationProblemDetails
yanıt verebileceğini belirtmek için kullanılabilir.
var app = WebApplication.Create();
var todos = app.MapGroup("/todos")
.ProducesProblem(StatusCodes.Status500InternalServerError);
todos.MapGet("/", () => new Todo(1, "Create sample app", false));
todos.MapPost("/", (Todo todo) => Results.Ok(todo));
app.Run();
record Todo(int Id, string Title, bool IsCompleted);
Problem
ve ValidationProblem
sonuç türleri, değerlerle IEnumerable<KeyValuePair<string, object?>>
yapılışı destekler
.NET 9'un öncesinde, ve özelliklerinin uygulamasıyla IDictionary<string, object?>
başlatılması için en az API'lerde errors
Sorun ve extensions
ValidationProblem sonuç türlerini oluşturma. Bu sürümde, bu yapı API'leri kullanan IEnumerable<KeyValuePair<string, object?>>
aşırı yüklemeleri destekler.
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);
});
Bu katkı için GitHub kullanıcısı joegoldman2'ye teşekkür ederiz!
Kimlik doğrulaması ve yetkilendirme
Bu bölümde kimlik doğrulaması ve yetkilendirmeye yönelik yeni özellikler açıklanmaktadır.
OpenIdConnectHandler, Gönderilen Yetkilendirme İstekleri (PAR) için destek ekler
ASP.NET Core'un OpenIdConnectHandler'sine Gönderilen Yetkilendirme İsteklerini (PAR) eklediği için Duende Software'ten Joe DeCock'a teşekkür ederiz. Joe, API teklifinde PAR'yi etkinleştirmenin arka planını ve motivasyonunu şu şekilde tanımladı:
Gönderilen Yetkilendirme İstekleri (PAR), yetkilendirme parametrelerini ön kanaldan arka kanala taşıyarak OAuth ve OIDC akışlarının güvenliğini geliştiren nispeten yeni bir OAuth standardıdır . Diğer bir ifadeyle, yetkilendirme parametrelerini tarayıcıdaki yeniden yönlendirme URL'lerinden makinenin arka uçtaki makine http çağrılarına yönlendirmesine taşıma.
Bu, tarayıcıda bir siber saldırının aşağıdakileri yapmasını önler:
- Kimlik doğrulama parametrelerinin görülmesi PII'yi sızdırabilir.
- Bu parametrelerle oynanıyor. Örneğin siber saldırı, istenen erişim kapsamını değiştirebilir.
Yetkilendirme parametrelerinin gönderilmesi, istek URL'lerini de kısa tutar. Yetkilendirme parametreleri, Zengin Yetkilendirme İstekleri gibi daha karmaşık OAuth ve OIDC özellikleri kullanılırken çok uzun sürebilir. Uzun olan URL'ler birçok tarayıcıda ve ağ altyapısında sorunlara neden olur.
PAR kullanımı, OpenID Foundation içindeki FAPI çalışma grubu tarafından teşvik edilir. Örneğin, FAPI2.0 Güvenlik Profili PAR kullanımını gerektirir. Bu güvenlik profili, açık bankacılık (öncelikli olarak Avrupa' da), sağlık hizmetlerinde ve yüksek güvenlik gereksinimleri olan diğer sektörlerde çalışan grupların çoğu tarafından kullanılır.
PAR, dahil olmak üzere bir dizi identity sağlayıcı tarafından desteklenir
.NET 9 için, sağlayıcının identity bulma belgesi PAR desteğini tanıtıyorsa PAR'yi varsayılan olarak etkinleştirmeye karar verdik, çünkü bunu destekleyen sağlayıcılar için gelişmiş güvenlik sağlamalıdır. Sağlayıcının identity bulma belgesi genellikle adresinde .well-known/openid-configuration
bulunur. Bu sorunlara neden olursa, AŞAĞıDAKI gibi OpenIdConnectOptions.PushedAuthorizationBehavior aracılığıyla PAR'yi devre dışı bırakabilirsiniz:
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;
});
Kimlik doğrulamasının yalnızca PAR kullanıldığında başarılı olduğundan emin olmak için bunun yerine PushedAuthorizationBehavior.Require komutunu kullanın. Bu değişiklik, OpenIdConnectEvents'e gönderilen yetkilendirme isteğini özelleştirmek veya el ile işlemek için kullanılabilecek yeni bir OnPushAuthorization olayı da sunar. Daha fazla ayrıntı için API teklifine bakın.
OIDC ve OAuth Parametre Özelleştirmesi
OAuth ve OIDC kimlik doğrulama işleyicileri artık genellikle yeniden yönlendirme sorgu dizesinin parçası AdditionalAuthorizationParameters
olarak eklenen yetkilendirme iletisi parametrelerini özelleştirmeyi kolaylaştırma seçeneğine sahiptir. .NET 8 ve önceki sürümlerinde bu, özel bir işleyicide özel OnRedirectToIdentityProvider bir geri çağırma veya geçersiz kılma BuildChallengeUrl yöntemi gerektirir. Aşağıda bir .NET 8 kodu örneği verilmişti:
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;
};
});
Yukarıdaki örnek artık aşağıdaki kodla basitleştirilebilir:
builder.Services.AddAuthentication().AddOpenIdConnect(options =>
{
options.AdditionalAuthorizationParameters.Add("prompt", "login");
options.AdditionalAuthorizationParameters.Add("audience", "https://api.example.com");
});
genişletilmiş HTTP.sys kimlik doğrulama bayraklarını yapılandırma
Windows kimlik doğrulamasının HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING
nasıl işleneceğini iyileştirmek için HTTP.sys yeni EnableKerberosCredentialCaching
ve özelliklerini kullanarak ve HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL
CaptureCredentials
HTTP.sys AuthenticationManager bayraklarını yapılandırabilirsiniz. Örneğin:
webBuilder.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.Negotiate;
options.Authentication.EnableKerberosCredentialCaching = true;
options.Authentication.CaptureCredentials = true;
});
Çeşitli
Aşağıdaki bölümlerde çeşitli yeni özellikler açıklanmaktadır.
Yeni HybridCache
kitaplık
API, HybridCache
mevcut IDistributedCache ve IMemoryCache API'lerdeki bazı boşlukları kapatır. Ayrıca aşağıdakiler gibi yeni özellikler de ekler:
- Aynı çalışmanın paralel getirilmesini önlemek için "Stampede" koruması .
- Yapılandırılabilir serileştirme.
HybridCache
var olan IDistributedCache
ve IMemoryCache
kullanım için açılan bir yerine geçecek şekilde tasarlanmıştır ve yeni önbelleğe alma kodu eklemek için basit bir API sağlar. Hem işlem içi hem de işlem dışı önbelleğe alma için birleşik bir API sağlar.
API'nin HybridCache
nasıl basitleştirildiğini görmek için api'yi kullanan IDistributedCache
kodla karşılaştırın. Kullanımın nasıl IDistributedCache
göründüğüne bir örnek aşağıda verilmişti:
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)
{ /* ... */ }
}
Serileştirme gibi şeyler de dahil olmak üzere her seferinde doğru olanı yapmak için çok fazla çalışma gerekir. Önbellek kaçırma senaryosunda birden çok eş zamanlı iş parçacığı elde edebilir, hepsi önbellek kaçırması alabilir, tüm temel alınan verileri getirebilir, hepsini seri hale getirebilir ve tüm bu verileri önbelleğe gönderebilirsiniz.
ile HybridCache
bu kodu basitleştirmek ve geliştirmek için öncelikle yeni kitaplığını Microsoft.Extensions.Caching.Hybrid
eklemeliyiz:
<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="9.0.0" />
HybridCache
Bir uygulamayı kaydeder gibi hizmeti kaydedinIDistributedCache
:
builder.Services.AddHybridCache(); // Not shown: optional configuration API.
Artık çoğu önbelleğe alma sorunu için HybridCache
boşaltılabilir:
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
);
}
}
Bağımlılık ekleme yoluyla soyut sınıfın HybridCache
somut bir uygulamasını sağlarız, ancak geliştiricilerin API'nin özel uygulamalarını sağlaması amaçlanmıştır. Uygulama, HybridCache
eşzamanlı işlem işleme dahil olmak üzere önbelleğe almayla ilgili her şeyi ele alır. Buradaki cancel
belirteç, yalnızca görebildiğimiz çağıranın iptalini (yani token
) değil, tüm eş zamanlı arayanların birleştirilmiş iptalini temsil eder.
Yakalanan değişkenlerin TState
ve örnek başına geri çağırmaların bazı ek yüklerini önlemek için yüksek aktarım hızı senaryoları desen kullanılarak daha da iyileştirilebilir:
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
, örneğin Redis kullanarak ikincil işlem dışı önbelleğe alma için yapılandırılan IDistributedCache
uygulamayı (varsa) kullanır. Ancak, bir IDistributedCache
HybridCache
olmadan bile hizmet işlem içi önbelleğe alma ve "damgalı" koruma sağlamaya devam eder.
Nesne yeniden kullanımıyla ilgili bir not
kullanan IDistributedCache
tipik mevcut kodda, önbellekten bir nesnenin her alınması seri durumdan çıkarılır. Bu davranış, her eşzamanlı çağıranın nesnenin diğer örneklerle etkileşim kuramayan ayrı bir örneğini aldığı anlamına gelir. Sonuç olarak iş parçacığı güvenliği elde edilir çünkü aynı nesne örneğinde eşzamanlı değişiklik yapılması riski yoktur.
Çok fazla HybridCache
kullanım mevcut IDistributedCache
koddan uyarlanacağından, HybridCache
eşzamanlılık hatalarının oluşmasını önlemek için bu davranışı varsayılan olarak korur. Ancak, belirli bir kullanım örneği doğal olarak iş parçacığı açısından güvenlidir:
- Önbelleğe alınan türler sabitse.
- Kod bunları değiştirmezse.
Bu gibi durumlarda örneklerin yeniden kullanılmasının güvenli olduğunu şu şekilde bildirin HybridCache
:
- Türü olarak
sealed
işaretleme.sealed
C# dilindeki anahtar sözcük, sınıfın devralınamaz olduğu anlamına gelir. - özniteliğini
[ImmutableObject(true)]
uygulama.[ImmutableObject(true)]
özniteliği, nesne oluşturulduktan sonra nesnenin durumunun değiştirilebileceğini gösterir.
Örnekleri yeniden kullanarak, HybridCache
çağrı başına seri durumdan çıkarma ile ilişkili CPU ve nesne ayırma yükünü azaltabilir. Bu, önbelleğe alınan nesnelerin büyük olduğu veya sık erişildiği senaryolarda performans geliştirmelerine yol açabilir.
Diğer HybridCache
özellikler
gibi IDistributedCache
, HybridCache
bir RemoveKeyAsync
yöntemle anahtara göre kaldırmayı destekler.
HybridCache
ayrıca, ayırmaları önlemek byte[]
için uygulamalar için IDistributedCache
isteğe bağlı API'ler sağlar. Bu özellik ve Microsoft.Extensions.Caching.SqlServer
paketlerinin önizleme sürümleri Microsoft.Extensions.Caching.StackExchangeRedis
tarafından uygulanır.
Serileştirme, çağrıdan zincirlenmiş ve .WithSerializerFactory
yöntemleri aracılığıyla WithSerializer
türe özgü ve genelleştirilmiş seri hale getiriciler desteğiyle hizmeti kaydetmenin AddHybridCache
bir parçası olarak yapılandırılır. Varsayılan olarak, kitaplık diğer her şeyi işler ve byte[]
dahili olarak işler string
ve kullanırSystem.Text.Json
, ancak protobuf, xml veya başka herhangi bir şeyi kullanabilirsiniz.
HybridCache
,NET Framework 4.7.2 ve .NET Standard 2.0'a kadar eski .NET çalışma zamanlarını destekler.
hakkında HybridCache
daha fazla bilgi için bkz. ASP.NET Core'da HybridCache kitaplığı
Geliştirici özel durum sayfası geliştirmeleri
ASP.NET Core geliştirici özel durum sayfası , geliştirme sırasında bir uygulama işlenmeyen bir özel durum oluşturduğunda görüntülenir. Geliştirici özel durumu sayfası, özel durum ve istek hakkında ayrıntılı bilgi sağlar.
Önizleme 3, geliştirici özel durum sayfasına uç nokta meta verileri ekledi. ASP.NET Core yönlendirme, yanıt önbelleğe alma, hız sınırlama, OpenAPI oluşturma ve daha fazlası gibi uç nokta davranışlarını denetlemek için uç nokta meta verilerini kullanır. Aşağıdaki görüntüde Routing
, geliştirici özel durum sayfasının bölümündeki yeni meta veri bilgileri gösterilmektedir:
Geliştirici özel durum sayfası test edilirken, küçük yaşam kalitesi iyileştirmeleri belirlendi. Önizleme 4'te gönderildi:
- Daha iyi metin kaydırma. Uzun tanımlama bilgileri, sorgu dizesi değerleri ve yöntem adları artık yatay tarayıcı kaydırma çubukları eklemez.
- Modern tasarımlarda bulunan daha büyük metin.
- Daha tutarlı tablo boyutları.
Aşağıdaki animasyonlu görüntüde yeni geliştirici özel durum sayfası gösterilmektedir:
Sözlük hata ayıklama geliştirmeleri
Sözlüklerin ve diğer anahtar-değer koleksiyonlarının hata ayıklama görüntüsü geliştirilmiş bir düzene sahiptir. Anahtar, değerle birleştirilmek yerine hata ayıklayıcının anahtar sütununda görüntülenir. Aşağıdaki görüntülerde, hata ayıklayıcıda bir sözlüğün eski ve yeni görünümü gösterilmektedir.
Önce:
Sonra:
ASP.NET Core'da birçok anahtar-değer koleksiyonu vardır. Bu geliştirilmiş hata ayıklama deneyimi şunlar için geçerlidir:
- HTTP üst bilgileri
- Sorgu dizeleri
- Formlar
- Tanımlama bilgileri
- Verileri görüntüleme
- Veri yönlendirme
- Özellikler
IIS'de uygulama geri dönüşümü sırasında 503'ler için düzeltme
Varsayılan olarak, IIS'ye geri dönüşüm veya kapatma bildirimi gönderilmesi ile ANCM'nin yönetilen sunucuya kapatmayı başlatmasını bildirmesi arasında 1 saniyelik bir gecikme vardır. Gecikme, ortam değişkeni aracılığıyla ANCM_shutdownDelay
veya işleyici ayarı ayarlanarak shutdownDelay
yapılandırılabilir. Her iki değer de milisaniye cinsindendir. Gecikme esas olarak aşağıdaki durumlarda bir yarışın olasılığını azaltmaktır:
- IIS, yeni uygulamaya gitmek için istekleri kuyruğa alma işlemini başlatmadı.
- ANCM, eski uygulamaya gelen yeni istekleri reddetmeye başlar.
Daha yavaş makineler veya daha ağır CPU kullanımına sahip makineler, 503 olasılığını azaltmak için bu değeri ayarlamak isteyebilir.
ayar shutdownDelay
örneği:
<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>
Düzeltme, barındırma paketinden gelen genel olarak yüklenmiş ANCM modülündedir.
Statik web varlığı teslimini iyileştirme
Statik varlıklara hizmet vermek için üretim için en iyi yöntemlerin takip etmek için önemli miktarda iş ve teknik uzmanlık gerekir. Sıkıştırma, önbelleğe alma ve parmak izi gibi iyileştirmeler olmadan:
- Tarayıcının her sayfa yüklemesinde ek istekler yapması gerekir.
- Gerekenden daha fazla bayt ağ üzerinden aktarılır.
- Bazen dosyaların eski sürümleri istemcilere sunulur.
Yüksek performanslı web uygulamaları oluşturmak için tarayıcıya varlık tesliminin iyileştirilmesi gerekir. Olası iyileştirmeler şunlardır:
- Dosya değişene veya tarayıcı önbelleğini temizleyene kadar belirli bir varlığa bir kez hizmet verin. ETag üst bilgisini ayarlayın.
- Bir uygulama güncelleştirildikten sonra tarayıcının eski veya eski varlıkları kullanmasını engelleyin. Son Değiştirme üst bilgisini ayarlayın.
- Uygun önbelleğe alma üst bilgilerini ayarlayın.
- Önbelleğe alma ara yazılımını kullanın.
- Mümkün olduğunda varlıkların sıkıştırılmış sürümlerini sunma.
- Varlıkları kullanıcıya daha yakın bir şekilde sunmak için CDN kullanın.
- Tarayıcıya sunulan varlıkların boyutunu en aza indirin. Bu iyileştirme, küçültmeyi içermez.
MapStaticAssets
, bir uygulamadaki statik varlıkların teslimini iyileştirmeye yardımcı olan yeni bir ara yazılımdır. , Razor Pages ve MVC dahil olmak üzere Blazortüm kullanıcı arabirimi çerçeveleriyle çalışacak şekilde tasarlanmıştır. Genellikle UseStaticFiles'ın yerine geçer:
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
bir uygulamadaki tüm statik kaynaklar hakkında bilgi toplamak için derleme ve yayımlama zamanı işlemlerini birleştirerek çalışır. Bu bilgiler daha sonra çalışma zamanı kitaplığı tarafından bu dosyaları tarayıcıya verimli bir şekilde sunmak için kullanılır.
MapStaticAssets
çoğu durumda yerini UseStaticFiles
alabilir, ancak uygulamanın derleme ve yayımlama zamanında bilgi sahibi olduğu varlıklara hizmet etmek için iyileştirilmiştir. Uygulama disk veya ekli kaynaklar UseStaticFiles
gibi diğer konumlardan varlıklara hizmet verirse kullanılmalıdır.
MapStaticAssets
ile UseStaticFiles
bulunmayan aşağıdaki avantajları sağlar:
- Uygulamadaki tüm varlıklar için derleme zamanı sıkıştırma:
gzip
geliştirme sırasında vegzip + brotli
yayımlama sırasında.- Tüm varlıklar, varlıkların boyutunu en aza indirme hedefiyle sıkıştırılır.
- İçerik tabanlı
ETags
: Her kaynağın değeri, içeriğin SHA-256 karması için Base64 kodlanmış dizesidir.Etags
Bu, tarayıcının yalnızca içeriği değiştirilmişse dosyayı yeniden indirmesini sağlar.
Aşağıdaki tabloda, varsayılan Razor Sayfalar şablonundaki CSS ve dosyaların özgün ve JS sıkıştırılmış boyutları gösterilmektedir:
Dosya | Özgün | Sıkıştırılmış | Azaltma Yüzdesi |
---|---|---|---|
bootstrap.min.css | 163 | 17.5 | 89.26% |
jquery.js | 89.6 | 28 | 68.75% |
bootstrap.min.js | 78,5 | 20 | 74.52% |
Toplam | 331.1 | 65.5 | 80.20% |
Aşağıdaki tabloda Fluent UI Blazor bileşenleri kitaplığı kullanılarak özgün ve sıkıştırılmış boyutlar gösterilmektedir:
Dosya | Özgün | Sıkıştırılmış | Azaltma Yüzdesi |
---|---|---|---|
akıcı.js | 384 | 73 | 80.99% |
fluent.css | 94 | 11 | 88.30% |
Toplam | 478 | 84 | 82.43% |
Toplam 478 KB sıkıştırılmamış ve 84 KB sıkıştırılmış için.
Aşağıdaki tabloda MudBlazorBlazor bileşen kitaplığı kullanılarak özgün ve sıkıştırılmış boyutlar gösterilmektedir:
Dosya | Özgün | Sıkıştırılmış | Azaltma |
---|---|---|---|
MudBlazor.min.css | 541 | 37,5 | 93.07% |
MudBlazor.min.js | 47.4 | 9.2 | 80.59% |
Toplam | 588.4 | 46,7 | 92.07% |
İyileştirme, kullanılırken MapStaticAssets
otomatik olarak gerçekleşir. Yeni JavaScript veya CSS gibi bir kitaplık eklendiğinde veya güncelleştirildiğinde, varlıklar derlemenin bir parçası olarak iyileştirilir. İyileştirme, daha düşük bant genişliğine veya güvenilir olmayan bağlantılara sahip olabilecek mobil ortamlar için özellikle yararlıdır.
Yeni dosya teslim özellikleri hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın:
Sunucuda dinamik sıkıştırmayı etkinleştirme ve kullanma MapStaticAssets
MapStaticAssets
, sunucuda dinamik sıkıştırmaya göre aşağıdaki avantajlara sahiptir:
- Sunucuya özgü bir yapılandırma olmadığından daha basittir.
- Varlıklar derleme zamanında sıkıştırıldığından daha yüksek performanslıdır.
- Geliştiricilerin, varlıkların minimum boyuta sahip olduğundan emin olmak için derleme işlemi sırasında fazladan zaman harcamasına olanak tanır.
MudBlazor sıkıştırmasını IIS dinamik sıkıştırma ve MapStaticAssets
ile karşılaştıran aşağıdaki tabloyu göz önünde bulundurun:
IIS gzip | MapStaticAssets | MapStaticAssets Azaltma |
---|---|---|
≅ 90 | 37,5 | 59% |
ASP0026: [Authorize] [AllowAnonymous] tarafından "uzaktan" geçersiz kılındığında uyarır
Bir özniteliğin [Authorize]
MVC eylemine bir öznitelikten [AllowAnonymous]
"daha yakın" yerleştirilmesinin özniteliği geçersiz kılıp yetkilendirmeyi zorlaması [AllowAnonymous]
sezgisel görünüyor. Ancak, bu durum mutlaka böyle değildir. Önemli olan özniteliklerin göreli sırasıdır.
Aşağıdaki kod, daha uzaktaki bir öznitelik tarafından daha yakın [Authorize]
bir [AllowAnonymous]
özniteliğin geçersiz kılındığı örnekleri gösterir.
[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
{
}
.NET 9 Preview 6'da, daha yakın [Authorize]
bir özniteliğin MVC eyleminden daha uzakta olan bir öznitelik tarafından geçersiz kılındığı örnekler gibi örnekleri vurgulayan bir [AllowAnonymous]
çözümleyici sunduk. Uyarı, geçersiz kılınan [Authorize]
özniteliğine şu iletiyle işaret ediyor:
ASP0026 [Authorize] overridden by [AllowAnonymous] from farther away
Bu uyarıyı görürseniz yapmanız gereken doğru eylem, özniteliklerin ardındaki amacına bağlıdır. [AllowAnonymous]
Uç nokta yanlışlıkla anonim kullanıcılara açıksa uzak özniteliği kaldırılmalıdır. Özniteliğin [AllowAnonymous]
daha yakın [Authorize]
bir özniteliği geçersiz kılması amaçlandıysa, amacı netleştirmek için özniteliğinden [Authorize]
sonra yineleyebilirsiniz[AllowAnonymous]
.
[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;
}
Geliştirilmiş Kestrel bağlantı ölçümleri
Bağlantının neden başarısız olduğuyla ilgili meta verileri ekleyerek 'nin bağlantı ölçümlerinde önemli bir iyileştirme Kestrelyaptık. Ölçüm kestrel.connection.duration
artık özniteliğinde bağlantı kapatma nedenini error.type
içerir.
Değerlerin error.type
küçük bir örneği aşağıda verilmiştir:
tls_handshake_failed
- Bağlantı TLS gerektiriyor ve TLS el sıkışması başarısız oldu.connection_reset
- İstekler devam ederken bağlantı istemci tarafından beklenmedik bir şekilde kapatıldı.request_headers_timeout
- Kestrel İstek üst bilgilerini zamanında almadığından bağlantıyı kapattı.max_request_body_size_exceeded
- Kestrel Karşıya yüklenen veriler boyut üst sınırını aştığından bağlantıyı kapattı.
Daha önce, bağlantı sorunlarını tanılamak Kestrel için sunucunun ayrıntılı, düşük düzeyli günlüğe kaydetmesi gerekiyordu. Ancak günlüklerin oluşturulması ve depolanması pahalı olabilir ve gürültü arasında doğru bilgileri bulmak zor olabilir.
Ölçümler, minimum etkiyle üretim ortamında bırakılabilen çok daha ucuz bir alternatiftir. Toplanan ölçümler panoları ve uyarıları yönlendirebilir. Ölçümlerle ilgili üst düzey bir sorun belirlendikten sonra, günlüğe kaydetme ve diğer araçları kullanarak daha fazla araştırma başlayabilir.
Geliştirilmiş bağlantı ölçümlerinin birçok senaryoda yararlı olmasını bekliyoruz:
- Kısa bağlantı ömründen kaynaklanan performans sorunlarını araştırma.
- Performansı ve kararlılığı etkileyen sürekli dış saldırıları Kestrel gözlemleme.
- 'nin yerleşik güvenlik sağlamlaştırması engellenen dış saldırı Kestrel Kestrelgirişimini kaydetme.
Daha fazla bilgi için bkz . ASP.NET Çekirdek ölçümleri.
Adlandırılmış kanal uç noktalarını özelleştirme Kestrel
Kestrel'nin adlandırılmış kanal desteği gelişmiş özelleştirme seçenekleriyle geliştirildi. Adlandırılmış kanal seçeneklerindeki yeni CreateNamedPipeServerStream
yöntem, kanalların uç nokta başına özelleştirilmesine olanak tanır.
Bunun yararlı olduğu bir örnek, farklı erişim güvenliğine sahip iki kanal uç noktası gerektiren bir Kestrel uygulamadır. bu CreateNamedPipeServerStream
seçenek, kanal adına bağlı olarak özel güvenlik ayarlarıyla kanal oluşturmak için kullanılabilir.
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
özel durum türüne göre durum kodunu seçme seçeneği
yapılandırırken yeni bir seçenek, uygulama geliştiricilerinin ExceptionHandlerMiddleware
istek işleme sırasında bir özel durum oluştuğunda hangi durum kodunun döndürüleceğini seçmesine olanak tanır. Yeni seçenek, yanıtta ProblemDetails
ayarlanan durum kodunu dosyasından ExceptionHandlerMiddleware
değiştirir.
app.UseExceptionHandler(new ExceptionHandlerOptions
{
StatusCodeSelector = ex => ex is TimeoutException
? StatusCodes.Status503ServiceUnavailable
: StatusCodes.Status500InternalServerError,
});
Belirli uç noktalarda ve isteklerde HTTP ölçümlerini geri çevirme
.NET 9, belirli uç noktalar ve istekler için HTTP ölçümlerini geri çevirme özelliğini tanıtır. Kayıt ölçümlerini geri çevirmek, sistem durumu denetimleri gibi otomatik sistemler tarafından sık çağrılan uç noktalar için yararlıdır. Bu isteklerin ölçümlerini kaydetmek genellikle gereksizdir.
Bir uç noktaya yönelik HTTP istekleri meta veriler eklenerek ölçümlerden dışlanabilir. Şunlardan biri:
[DisableHttpMetrics]
Özniteliğini Web API denetleyicisine, SignalR hub'a veya gRPC hizmetine ekleyin.- Uygulama başlangıcında uç noktaları eşlerken DisableHttpMetrics çağrısı yapın:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/healthz").DisableHttpMetrics();
app.Run();
MetricsDisabled
özelliği için eklendiIHttpMetricsTagsFeature
:
- İsteğin bir uç noktaya eşlendiği gelişmiş senaryolar.
- Belirli HTTP istekleri için ölçüm koleksiyonunu dinamik olarak devre dışı bırakma.
// 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);
});
Anahtarları silmek için Data Protection desteği
.NET 9'un öncesinde veri koruma anahtarları, veri kaybını önlemek için tasarım gereği temsilci seçilemezdi. Bir anahtarın silinmesi, korunan verileri kurtarılamaz hale getirir. Küçük boyutları göz önüne alındığında, bu anahtarların birikmesi genellikle en az etkiye neden oldu. Ancak, son derece uzun süre çalışan hizmetleri barındırmak için anahtarları silme seçeneğini kullanıma sunmuş olduk. Genel olarak, yalnızca eski anahtarların silinmesi gerekir. Anahtarları yalnızca depolama tasarrufu karşılığında veri kaybı riskini kabul ettiğinizde silin. Veri koruma anahtarlarının silinmemesi önerilir.
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.");
}
Ara yazılım Keyed DI'i destekler
Ara yazılım artık hem oluşturucuda hem de yönteminde Keyed DI'yiInvokeAsync
/Invoke
destekliyor:
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);
}
Linux'ta ASP.NET Core HTTPS geliştirme sertifikasına güvenme
Ubuntu ve Fedora tabanlı Linux dağıtımlarında artık dotnet dev-certs https --trust
ASP.NET Core HTTPS geliştirme sertifikasını güvenilen sertifika olarak yapılandırmaktadır:
- Google Chrome, Microsoft Edge ve Chromium gibi Chromium tarayıcıları.
- Mozilla Firefox ve Mozilla türetilmiş tarayıcılar.
- .NET API'leri, örneğin, HttpClient
Daha önce yalnızca --trust
Windows ve macOS üzerinde çalışıyordu. Sertifika güveni kullanıcı başına uygulanır.
OpenSSL'de dev-certs
güven oluşturmak için araç:
- Sertifikayı
~/.aspnet/dev-certs/trust
- Dizinde OpenSSL'nin c_rehash aracının basitleştirilmiş bir sürümünü çalıştırır.
- Kullanıcıdan ortam değişkenini güncelleştirmesini
SSL_CERT_DIR
ister.
Dotnet'te güven oluşturmak için araç sertifikayı sertifika deposuna My/Root
yerleştirir.
Varsa, NSS veritabanlarında güven oluşturmak için araç, dizininde home Firefox profilleri, ~/.pki/nssdb
ve ~/snap/chromium/current/.pki/nssdb
için arar. Araç, bulunan her dizin için öğesine nssdb
bir girdi ekler.
Şablonlar en son Bootstrap, jQuery ve jQuery Doğrulama sürümlerine güncelleştirildi
ASP.NET Core proje şablonları ve kitaplıkları, özellikle de Bootstrap, jQuery ve jQuery Doğrulaması'nın en son sürümlerini kullanacak şekilde güncelleştirildi:
- Bootstrap 5.3.3
- jQuery 3.7.1
- jQuery Doğrulama 1.21.0
ASP.NET Core