Aracılığıyla paylaş


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 Önizleme 6 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.
  • Web Uygulaması (genel Etkileşimli Otomatik işleme) ve bir Blazor uygulama da dahil olmak üzere uygun projelerin otomatik olarak .NET MAUIBlazor Hybrid oluşturulması.
  • 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 Blazor Web Uygulaması 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.

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 Blazor. WebView, ResolveComponentForRenderMode (dotnet/aspnetcore #51235) geçersiz kılmayı etkinleştirmek için bir yönteme ihtiyaç duyar.

Daha fazla bilgi için bkz. Web Uygulaması ile Blazor uygulama 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:

Ç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.

Web Apps için Blazor basitleştirilmiş kimlik doğrulama durumu serileştirmesi

Yeni API'ler, mevcut Blazor bir Web Uygulamasına kimlik doğrulaması eklemeyi kolaylaştırır. Tek Tek Hesapları kullanarak kimlik doğrulamasıyla yeni Blazor bir Web Uygulaması 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 çalışma zamanı başlatılmadan önce kimlik doğrulama durumuna erişmesine Blazor WebAssembly 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.

Web Uygulaması proje şablonundan Blazor 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 kullanmanız iyi olur. Artık web uygulaması proje şablonunun Blazor parçası 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** makalenin aşağıdaki bölümlerine bakın:

Genel olarak etkileşimli Blazor bir Web Uygulamasına statik sunucu tarafı işleme (SSR) sayfaları ekleme

.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, HTTP'leri cookieokumaya/yazmaya 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 @attributeRazor 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ılan InteractiveServer olarak ek açıklama eklenmemiş sayfalar. veya ile InteractiveWebAssembly InteractiveAuto değiştirerek InteractiveServer farklı bir varsayılan genel işleme modu belirtebilirsiniz.
  • Statik SSR'yi benimseme ile [ExcludeFromInteractiveRouting] ek açıklamalı sayfalar (PageRenderMode atanır null).
<!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()?.Metadatauç 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)
{
    protected NavigationManager Navigation { get; } = navigation;
}

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 nullve 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:

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>

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 .NET Aspire panosu ve OpenTelemetry paketleri kullanılmaktadı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:

// 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:

Hub yöntemi çağrı olayları için SignalR etkinlik listesi

Minimal API'ler

Bu bölümde en düşük API'lere yönelik yeni özellikler açıklanmaktadır.

ve InternalServerError<TValue> eklendi InternalServerErrorTypedResults

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();

OpenAPI

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 belgesi

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.

Derleme zamanında OpenAPI belgesi oluşturma

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:

OpenAPI tamamlamaları

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.

Otomatik paket yükleme

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.UseSchemaTransformer((schema, context, cancellationToken) =>
    {
        if (context.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; }
}

Kimlik doğrulaması ve yetkilendirme

Bu bölümde kimlik doğrulaması ve yetkilendirmeye yönelik yeni özellikler açıklanmaktadır.

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 IDistributedCachekodla 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 HybridCachebu kodu basitleştirmek ve geliştirmek için öncelikle yeni kitaplığını Microsoft.Extensions.Caching.Hybrideklemeliyiz:

<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="9.0.0" />

HybridCache Bir uygulamayı kaydeder gibi hizmeti kaydedinIDistributedCache:

services.AddHybridCache(); // Not shown: optional configuration API.

Artık çoğu önbelleğe alma sorunu için HybridCacheboş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 IDistributedCacheHybridCache 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 IDistributedCachetipik 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 sealediş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.

HybridCacheayrı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 HybridCachedaha 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ındaki yeni meta veri bilgileri

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 cookies, 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:

Yeni geliştirici özel durum sayfası

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:

Önceki hata ayıklayıcı deneyimi

Sonra:

Yeni hata ayıklayıcı deneyimi

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
  • Cookies
  • 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 UseStaticFilesbulunmayan 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 ve gzip + 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
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, MudBlazorBlazor bileşenleri kitaplığını kullanan özgün ve sıkıştırılmış boyutlar gösterilmektedir:

Dosya Özgün Sıkıştırılmış Azaltma
ÇamurBlazor.min.css 541 37,5 93.07%
ÇamurBlazor.min.js 47.4 9.2 80.59%
Toplam 588.4 46,7 92.07%

İyileştirme, kullanılırken MapStaticAssetsotomatik 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.

ÇamurBlazor sıkıştırmasını IIS dinamik sıkıştırma ve MapStaticAssetsile 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;
}