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.
Statik içerik teslimatını iyileştirme
MapStaticAssets
yönlendirme uç noktası kuralları , ASP.NET Core uygulamalarında statik varlıkların teslimini en iyi duruma getiren yeni bir özelliktir.
Blazor uygulamaları için statik varlık teslimi hakkında bilgi için bkz: ASP.NET Core Blazor statik dosyalar.
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 en iyi duruma getiren yeni bir özelliktir. , Blazor Pages ve MVC dahil olmak üzere Razortüm kullanıcı arabirimi çerçeveleriyle çalışacak şekilde tasarlanmıştır. Genellikle UseStaticFiles
için doğrudan bir yedektir.
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 gömülü kaynaklar gibi farklı konumlardan varlıklar sağlıyorsa, UseStaticFiles
kullanılmalıdır.
MapStaticAssets
ile UseStaticFiles
bulunmayan aşağıdaki avantajları sağlar:
- Uygulamadaki tüm kayıtların derleme süresi sıkıştırması:
-
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ğınEtags
içeriğinin SHA-256 karmasının Base64 ile kodlanmış dizgesidir. 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 JS Sayfalar şablonundaki CSS ve dosyaların özgün ve Razor 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 |
---|---|---|---|
fluent.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 MudBlazor bileşen kütüphanesini kullanarak orijinal 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, kaynaklar derlemenin bir parçası olarak optimize edilir. İ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 ile kullanma karşılaştırması
MapStaticAssets
, sunucuda dinamik sıkıştırmaya göre aşağıdaki avantajlara sahiptir:
- Sunucuya özgü bir yapılandırma olmadığından daha basittir.
- Kaynaklar derleme zamanında sıkıştırıldığı için daha fazla performans gösterir.
- 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% |
Blazor
Bu bölümde için Blazoryeni özellikler açıklanmaktadır.
.NET MAUI Blazor Hybrid ve Web App çözüm şablonu
Yeni bir çözüm şablonu, aynı kullanıcı arabirimini paylaşan yerel ve .NET MAUI web istemcisi uygulamaları oluşturmayı Blazor 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.
- Uygun projelerin otomatik oluşturulması, Blazor Web App (genel Etkileşimli Otomatik işleme) ve bir .NET MAUIBlazor Hybrid uygulaması dahil olmak üzere.
- Oluşturulan projeler, kullanıcı arabiriminin Razor bileşenlerini korumak için paylaşılan Razor bir sınıf kitaplığı (RCL) kullanır.
- Blazor Hybrid uygulaması ve Blazor Web App için farklı arabirim uygulamaları sağlamak amacıyla bağımlılık enjeksiyonu nasıl kullanılır gösteren örnek kod eklenmiştir.
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: .NET MAUIBlazor Hybrid uygulama oluşturma Blazor Web App ile.
Ç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, 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.
Blazor Web App'ler için basitleştirilmiş kimlik doğrulama durumu serileştirmesi
Yeni API'ler, mevcut Blazor Web Appbir öğesine kimlik doğrulaması eklemeyi kolaylaştırır. Bireysel Hesaplar
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 yorumlarına dönüştürmek ve WebAssembly'den geri okuyarak yeni bir AuthenticationState örneği oluşturmak için Kalıcı Bileşen Durumu hizmetini kullanır (PersistentComponentState).
Bu, Blazor Web App proje şablonundan başlayıp Bireysel Hesaplar seçeneğini belirlediyseniz iyi çalışır, ancak mevcut bir projeye kimlik doğrulaması eklemeye çalışırken kendiniz uygulamak veya kopyalamak için çok fazla kod vardır. 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 deserilize etmek 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 bir seçenek (AddAuthenticationStateSerialization) geçirilebilir.
Daha fazla bilgi için ASP.NET Core Blazor kimlik doğrulaması ve yetkilendirmesinin aşağıdaki bölümlerine bakın:
- Blazor Identity Kullanıcı Arayüzü (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, uygulamanın etkileşimli Sunucu veya WebAssembly işleme ile çalışamayan belirli sayfaları olduğunda faydalıdır. Örneğin, HTTP tanımlama bilgilerini okuma/yazmaya bağlı 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.
Yeni [ExcludeFromInteractiveRouting]
özniteliğiyle@attribute
Razor yönergesi atanmış herhangi bir Razor bileşen sayfasını işaretleyin.
@attribute [ExcludeFromInteractiveRouting]
Bu özniteliğin uygulanması, sayfa navigasyonunun 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.
RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting uzantı yöntemi, bileşenin özniteliğin [ExcludeFromInteractiveRouting]
geçerli sayfaya uygulanıp uygulanmadığını algılamasına olanak tanır.
Bileşeninde App
, aşağıdaki örnekteki deseni kullanın:
-
[ExcludeFromInteractiveRouting]
özniteliği ile ek açıklama eklenmemiş sayfalar, varsayılan olarakInteractiveServer
genel etkileşimli işleme modunda çalışır.InteractiveServer
öğesiniInteractiveWebAssembly
veyaInteractiveAuto
ile değiştirerek farklı bir varsayılan genel işleme modu belirtebilirsiniz. -
[ExcludeFromInteractiveRouting]
özniteliğiyle etiketlenmiş sayfalar, statik SSR'yi benimser (PageRenderMode
null
olarak atanır).
<!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;
}
RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting uzantı yöntemini kullanmanın bir alternatifi, HttpContext.GetEndpoint()?.Metadata
kullanarak uç nokta meta verilerini el ile okumaktır.
Bu özellik, ASP.NET Core Blazor işleme modlarındaki başvuru belgeleri kapsamındadır.
Yapıcı enjeksiyonu
Razor bileşenler oluşturucu enjeksiyonunu destekler.
Aşağıdaki örnekte, kısmi (kod arkası) sınıfı birincil oluşturucu kullanarak NavigationManager
hizmeti enjekte ediyor.
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 İçerik Güvenliği Politikası (CSP) talimatlarını 'self'
olarak ayarlar. Sıkıştırma etkinleştirildiğinde veya WebSocket bağlamı için bir yapılandırma sağlandığında, uygulamanın sadece sunulduğu kaynağın bir <iframe>
içine yerleştirilmesine izin verir.
Sıkıştırma, ConfigureWebSocketOptions
olarak null
ayarlandığında devre dışı bırakılabilir, bu da uygulamanın saldırıya karşı güvenlik açığını azaltır ancak performansı düşürebilir.
.AddInteractiveServerRenderMode(o => o.ConfigureWebSocketOptions = null)
WebSocket sıkıştırmasına izin veren, ancak tarayıcıların uygulamayı herhangi bir frame-ancestors
içine eklemesini engelleyen daha katı bir <iframe>
CSP'yi, (tek tırnak gereklidir) 'none'
değeriyle 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
Blazor uygulamasında klavye kompozisyonu olaylarını işleyin
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.
OverscanCount
özelliğine QuickGrid
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, genellikle metin kutusu yerine kaydırıcı veya kadran kontrolü olarak işlenen ve model bağlamayı ve form doğrulamayı destekleyen bir aralık girişi oluşturan type="range"
ö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; }
}
}
Yeni gelişmiş gezinti olayları
Yeni olay dinleyicileriyle gelişmiş gezinti öncesinde veya sonrasında JavaScript geri çağırmalarını tetikleme:
blazor.addEventListener("enhancednavigationstart", {CALLBACK})
blazor.addEventListener("enhancednavigationend", {CALLBACK})
Daha fazla bilgi için bkz. ASP.NET Core Blazor JavaScript ile statik sunucu tarafı işleme (statik SSR).
İstemci tarafında istek akışı
Blazor'de Etkileşimli WebAssembly işleme artık HttpRequestMessage
üzerindeki request.SetBrowserReqeustStreamingEnabled(true)
seçeneğini kullanarak istemci taraflı istek akışını destekliyor.
Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:
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; }
}
SignalR için Geliştirilmiş Etkinlikler
SignalR artık hem merkez sunucusu hem de istemci için bir ActivitySource'a sahip.
.NET SignalR sunucusu ActivitySource
SignalR olarak adlandırılan Microsoft.AspNetCore.SignalR.Server
ActivitySource, hub metodu çağrıları için olayları tetikler.
- 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 örnek, .NET Aspire gösterge paneli ve OpenTelemetry paketlerini kullanır:
<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:
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şağıda Aspire Panosu'ndan alınan örnek çıkış verilmiştir:
.NET SignalR istemcisi ActivitySource
SignalR adlı Microsoft.AspNetCore.SignalR.Client
ActivitySource, SignalR istemcisi için olayları yayar:
- .NET SignalR istemcisinin
ActivitySource
adlı birMicrosoft.AspNetCore.SignalR.Client
vardır. Hub çağrıları artık bir istemci yayılma alanı oluşturur. JavaScript istemcisi gibi diğer SignalR istemcilerinin izlemeyi desteklemediğini unutmayın. Bu özellik, gelecek sürümlerde daha fazla istemciye eklenecektir. - İstemci ve sunucudaki hub çağrıları bağlam yaymadestekler. İzleme bağlamını yaymak, gerçek dağıtılmış izlemeyi etkinleştirir. Artık çağrıların istemciden sunucuya ve geriye doğru akışını görmek mümkündür.
İşte bu yeni etkinliklerin .NET Aspire kontrol panelinde nasıl göründüğü:
Aspire panosunda
SignalR kırpmayı ve Doğal AOT'yi destekler
.NET 8'de başlayan Yerel AOT yolculuğuna devam ederek, hem istemci hem de SignalR sunucu senaryoları için kırpmayı ve yerel önceden derlemeyi (AOT) destekleyecek şekilde 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şlangıç Adımları
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 sunucusunda, türü
IAsyncEnumerable<T>
veChannelReader<T>
olan veT
bir ValueType (struct
) olan 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> kullanımı (dotnet/aspnetcore
#56179). -
Güçlü bir şekilde yazılan hub'lar, Native AOT (
PublishAot
) ile 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.
InternalServerError
ve InternalServerError<TValue>
, TypedResults
'ye eklendi
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 ProblemDetails
veya ValidationProblemDetails
yanıtları döndürebileceğini belirtir.
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
ve ValidationProblem
sonuç türleri, IEnumerable<KeyValuePair<string, object?>>
değerleri ile yapıyı destekler.
.NET 9'dan önce, minimal API'lerde Problem ve ValidationProblem sonuç türlerini oluşturmak için, errors
ve extensions
özelliklerinin bir IDictionary<string, object?>
implementasyonu ile başlatılması gerekiyordu. Bu sürümde, inşaat API'leri IEnumerable<KeyValuePair<string, object?>>
aşırı yüklemelerini 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!
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'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
Uygulamayı çalıştırın ve oluşturulan OpenAPI belgesini görüntülemek için adresine gidin openapi/v1.json
:
OpenAPI belgeleri, Microsoft.Extensions.ApiDescription.Server
paketi eklenerek derleme zamanında da oluşturulabilir.
dotnet add package Microsoft.Extensions.ApiDescription.Server
Yayılan OpenAPI belgelerinin konumunu değiştirmek için, uygulamanın proje dosyasındaki OpenApiDocumentsDirectory özelliğinde hedef yolu ayarlayın:
<PropertyGroup>
<OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)</OpenApiDocumentsDirectory>
</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, işlem ve şema dönüştürücüleri 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.
Microsoft.AspNetCore.OpenApi kırpmayı ve Yerel AOT'yi destekler
ASP.NET Core'da OpenAPI kırpmayı ve yerel AOT'yi destekler. Aşağıdaki adımlar, gereksiz parçaların kaldırılması ve yerel AOT ile bir OpenAPI uygulaması oluşturup yayımlar:
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
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
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'tenJoe 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 parametrelerinin tarayıcıdaki yönlendirme URL'lerinden arka uçta doğrudan makineden makineye http çağrılarına taşınması.
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 kimlik sağlayıcısı tarafından desteklenir
.NET 9 için, kimlik sağlayıcısının bulma belgesi PAR desteğini tanıtıyorsa varsayılan olarak PAR'yi etkinleştirmeye karar verdik, çünkü bunu destekleyen sağlayıcılar için gelişmiş güvenlik sağlamalıdır. Kimlik sağlayıcısının bulma belgesi genellikle .well-known/openid-configuration
konumunda 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ı olmasını sağlamak için bunun yerine PushedAuthorizationBehavior.Require 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 bir OnRedirectToIdentityProvider geri çağırma işlevi veya geçersiz kılınmış bir 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 nasıl işleneceğini optimize etmek için HTTP.sys üzerindeki yeni EnableKerberosCredentialCaching
ve CaptureCredentials
özelliklerini kullanarak HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING
ve HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL
HTTP.sys AuthenticationManager bayraklarını şimdi 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
Önemli
HybridCache
şu anda önizleme aşamasındadır, ancak .NET Uzantıları'nın gelecekteki küçük bir sürümünde .NET 9.0'ın ardından tamamen yayımlanacaktır.
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
, mevcut IDistributedCache
ve IMemoryCache
kullanımları için doğrudan bir alternatif olarak tasarlanmıştır ve yeni önbellekleme 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. İşte IDistributedCache
kullanımının nasıl göründüğüne bir örnek:
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ığı olabilir, hepsi cache miss ile karşılaşabilir, hepsi temel verileri getirebilir, hepsi bunları seri hale getirebilir ve verilerin hepsini önbelleğe gönderebilir.
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 HybridCache
'a devredilebilir.
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şlemlerin yönetimi dahil olmak üzere önbelleğe almayla ilgili her şeyi ele alır. Buradaki cancel
belirteç, yalnızca görebildiğimiz çağıranın iptalini değil, tüm eşzamanlı arayanların birleştirilmiş iptalini temsil eder—yani, token
çağıranın iptali de dahil.
Yüksek aktarım hızı senaryoları, TState
desen kullanılarak yakalanan değişkenlerden ve her bir örnek için yapılan geri çağırmalardan kaynaklanan bazı ek yükleri önlemek amacıyla daha da optimize edilebilir.
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
olmadan bile, HybridCache
hizmeti işlem içi önbelleğe alma ve "sel koruması" sağlamaya devam eder.
Nesne yeniden kullanımıyla ilgili bir not
Tipik mevcut IDistributedCache
kullanan kodda, önbellekten her nesne alımı, nesnenin seri durumdan çıkarılmasına neden olur. 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 sağlanır çü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ği
[ImmutableObject(true)]
üzerine uygulamak.[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, IDistributedCache
uygulamaları için, byte[]
ayırmalarını önlemek amacıyla isteğe bağlı API'ler sağlar. Bu özellik, Microsoft.Extensions.Caching.StackExchangeRedis
ve Microsoft.Extensions.Caching.SqlServer
paketlerinin önizleme sürümleri tarafından uygulanır.
Hizmeti kaydetmenin bir parçası olarak serileştirme yapılandırılır ve AddHybridCache
çağrısından zincirlenerek WithSerializer
ve .WithSerializerFactory
yöntemleri aracılığıyla türe özgü ve genelleştirilmiş serileştiriciler için destek sunar. Varsayılan olarak, kitaplık string
ve byte[]
öğelerini dahili olarak işler ve diğer her şey için System.Text.Json
kullanır, ancak protobuf, xml veya başka herhangi bir şeyi de 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 yayınlandı."
- 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ı oluşturmaz.
- 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
- Çerezler
- Verileri görüntüleme
- Rota verisi
- Özellikler
IIS'te uygulama geri dönüşümü esnasında oluşan 503 hatalarının düzeltilmesi
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, ANCM_shutdownDelay
ortam değişkeni veya shutdownDelay
işleyici ayarı ile 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.
ASP0026: [Authorize] özniteliğinin daha uzaktan [AllowAnonymous] ile geçersiz kılındığında uyarı veren analiz aracı
MVC eylemine, bir [AllowAnonymous]
özniteliğinden "daha yakın" yerleştirilmiş bir [Authorize]
özniteliğinin, [AllowAnonymous]
özniteliğini geçersiz kılıp yetkilendirmeyi zorlaması sezgisel olarak mantıklı 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 olan [Authorize]
özniteliğinin MVC eyleminden daha uzakta olan bir [AllowAnonymous]
özniteliği tarafından geçersiz kılındığı durumları vurgulayan bir çözümleyici tanıttık. 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. Eğer uç nokta yanlışlıkla anonim kullanıcılara açıksa, [AllowAnonymous]
uzaklık özniteliği kaldırılmalıdır. tr-TR: Eğer [AllowAnonymous]
özniteliği, daha yakın [Authorize]
özniteliğini geçersiz kılmayı amaçlıyorsa, amacı netleştirmek için [Authorize]
özniteliğinden sonra [AllowAnonymous]
özniteliğini tekrarlayabilirsiniz.
[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 artık kestrel.connection.duration
özniteliğinde error.type
bağlantı kapatma nedenini 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ük kaydı yapması 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. Yüksek seviyeli bir sorun ölçümlerle belirlendikten sonra, daha fazla araştırmaya günlüğe kaydetme ve diğer araçları kullanarak başlanabilir.
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.
- Yerleşik güvenlik sağlamlaştırması tarafından engellenen KestrelKestrel üzerindeki dış saldırı girişimlerini 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, ProblemDetails
yanıtındaki ayarlanan durum kodunu ExceptionHandlerMiddleware
olarak 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 IHttpMetricsTagsFeature
için eklendi:
- Uç noktaya eşlenmeyen bir isteğin olduğu 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 kaybını önlemek için tasarım gereği veri koruma anahtarları silinemezdi. 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 InvokeAsync
yönteminde Keyed DI desteğini destekliyorInvoke
/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);
}
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 güven oluşturmak için dev-certs
aracını kullanın:
- Sertifikayı
~/.aspnet/dev-certs/trust
içine koyar. - 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.
NSS veritabanlarında güven oluşturmak için, varsa, araç ana dizinde Firefox profillerini arar, ~/.pki/nssdb
ve ~/snap/chromium/current/.pki/nssdb
. Araç, bulunan her dizin için nssdb
içine bir kayıt 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