Bagikan melalui


Apa yang baru dalam ASP.NET Core 6.0

Artikel ini menyoroti perubahan paling signifikan dalam ASP.NET Core 6.0 dengan tautan ke dokumentasi yang relevan.

ASP.NET Core MVC dan Razor peningkatan

Minimal API

API minimal dirancang untuk membuat API HTTP dengan dependensi minimal. Mereka sangat ideal untuk layanan mikro dan aplikasi yang hanya ingin menyertakan file, fitur, dan dependensi minimum di ASP.NET Core. Untuk informasi selengkapnya, lihat:

SignalR

Tag aktivitas yang berjalan lama untuk SignalR koneksi

SignalR menggunakan yang baru Microsoft.AspNetCore.Http.Features.IHttpActivityFeature.Activity untuk menambahkan http.long_running tag ke aktivitas permintaan. IHttpActivityFeature.Activity digunakan oleh layanan APM seperti Azure Monitor Application Insights untuk memfilter SignalR permintaan agar tidak membuat pemberitahuan permintaan yang berjalan lama.

Peningkatan performa SignalR

  • Alokasikan HubCallerClients sekali per koneksi alih-alih setiap panggilan metode hub.
  • Hindari penutupan alokasi di SignalRDefaultHubDispatcher.Invoke. Status diteruskan ke fungsi statis lokal melalui parameter untuk menghindari alokasi penutupan. Untuk informasi selengkapnya, lihat permintaan pull GitHub ini.
  • Alokasikan satu StreamItemMessage per streaming alih-alih per item streaming dalam streaming server-ke-klien. Untuk informasi selengkapnya, lihat permintaan pull GitHub ini.

Razor kompilator

Razor compiler diperbarui untuk menggunakan generator sumber

Pengkompilasi Razor sekarang didasarkan pada generator sumber C#. Generator sumber berjalan selama kompilasi dan periksa apa yang sedang dikompilasi untuk menghasilkan file tambahan yang dikompilasi bersama dengan sisa proyek. Menggunakan generator sumber menyederhanakan Razor pengkompilasi dan secara signifikan mempercepat waktu build.

Razor compiler tidak lagi menghasilkan rakitan Tampilan terpisah

Kompilator Razor sebelumnya menggunakan proses kompilasi dua langkah yang menghasilkan rakitan Tampilan terpisah yang berisi tampilan dan halaman (.cshtml file) yang dihasilkan yang ditentukan dalam aplikasi. Jenis yang dihasilkan adalah publik dan di AspNetCore bawah namespace layanan.

Pengkompilasi yang diperbarui Razor membangun tampilan dan jenis halaman ke dalam perakitan proyek utama. Jenis ini sekarang dihasilkan secara default sebagai internal yang AspNetCoreGeneratedDocument disegel di namespace layanan. Perubahan ini meningkatkan performa build, memungkinkan penyebaran file tunggal, dan memungkinkan jenis ini untuk berpartisipasi dalam Hot Reload.

Untuk informasi selengkapnya tentang perubahan ini, lihat masalah pengumuman terkait di GitHub.

performa ASP.NET Core dan peningkatan API

Banyak perubahan dilakukan untuk mengurangi alokasi dan meningkatkan performa di seluruh tumpukan:

Mengurangi jejak memori untuk koneksi TLS diam

Untuk koneksi TLS yang berjalan lama di mana data hanya sesekali dikirim bolak-balik, kami telah secara signifikan mengurangi jejak memori aplikasi ASP.NET Core di .NET 6. Ini akan membantu meningkatkan skalabilitas skenario seperti server WebSocket. Hal ini dimungkinkan karena banyak peningkatan dalam System.IO.Pipelines, , SslStreamdan Kestrel. Bagian berikut merinci beberapa peningkatan yang telah berkontribusi pada pengurangan jejak memori:

Kurangi ukuran System.IO.Pipelines.Pipe

Untuk setiap koneksi yang dibuat, dua pipa dialokasikan dalam Kestrel:

  • Lapisan transportasi ke aplikasi untuk permintaan tersebut.
  • Lapisan aplikasi ke transportasi untuk respons.

Dengan menyusutkan ukuran dari 368 byte menjadi 264 byte (sekitar pengurangan System.IO.Pipelines.Pipe 28,2%), 208 byte per koneksi disimpan (104 byte per Pipa).

Pool SocketSender

SocketSender objek (subkelas SocketAsyncEventArgsitu) sekitar 350 byte saat runtime. Alih-alih mengalokasikan objek baru SocketSender per koneksi, objek dapat dikumpulkan. SocketSender objek dapat dikumpulkan karena pengiriman biasanya sangat cepat. Pengumpulan mengurangi overhead per koneksi. Alih-alih mengalokasikan 350 byte per koneksi, hanya bayar 350 byte per IOQueue yang dialokasikan. Alokasi dilakukan per antrean untuk menghindari pertikaian. Server WebSocket kami dengan 5000 koneksi diam dari mengalokasikan ~ 1,75 MB (350 byte * 5000) untuk mengalokasikan ~ 2,8 kb (350 byte * 8) untuk SocketSender objek.

Pembacaan byte nol dengan SslStream

Bacaan tanpa buffer adalah teknik yang digunakan di ASP.NET Core untuk menghindari penyewaan memori dari kumpulan memori jika tidak ada data yang tersedia di soket. Sebelum perubahan ini, server WebSocket kami dengan 5000 koneksi menganggur diperlukan ~ 200 MB tanpa TLS dibandingkan dengan ~ 800 MB dengan TLS. Beberapa alokasi ini (4k per koneksi) adalah dari Kestrel harus berpegang pada ArrayPool<T> buffer sambil menunggu pembacaan SslStream selesai. Mengingat bahwa koneksi ini menganggur, tidak ada bacaan yang selesai dan mengembalikan buffer mereka ke ArrayPool, memaksa ArrayPool untuk mengalokasikan lebih banyak memori. Alokasi yang tersisa itu SslStream sendiri: buffer 4k untuk jabat tangan TLS dan buffer 32k untuk bacaan normal. Di .NET 6, ketika pengguna melakukan pembacaan SslStream byte nol dan tidak memiliki data yang tersedia, SslStream secara internal melakukan pembacaan byte nol pada aliran yang dibungkus yang mendasar. Dalam kasus terbaik (koneksi diam), perubahan ini menghasilkan penghematan 40 Kb per koneksi sambil tetap mengizinkan konsumen (Kestrel) untuk diberi tahu ketika data tersedia tanpa menahan buffer yang tidak digunakan.

Pembacaan byte nol dengan PipeReader

Dengan bacaan tanpa buffer yang didukung pada SslStream, opsi ditambahkan untuk melakukan pembacaan byte nol ke StreamPipeReader, jenis internal yang mengadaptasi Stream menjadi PipeReader. Dalam Kestrel, digunakanStreamPipeReader untuk mengadaptasi yang mendasar SslStream menjadi PipeReader. Oleh karena itu perlu untuk mengekspos semantik baca byte nol ini pada PipeReader.

Sekarang PipeReader dapat dibuat yang mendukung pembacaan nol byte atas dasar apa pun Stream yang mendukung semantik baca byte nol (misalnya, SslStream, NetworkStream, dll) menggunakan API berikut:

var reader = PipeReader.Create(stream, new StreamPipeReaderOptions(useZeroByteReads: true));

Menghapus slabs dari SlabMemoryPool

Untuk mengurangi fragmentasi tumpukan, Kestrel menggunakan teknik di mana ia mengalokasikan lempung memori 128 KB sebagai bagian dari kumpulan memorinya. Slabs kemudian dibagi lebih lanjut menjadi 4 KB blok yang digunakan oleh Kestrel internal. Lempengan harus lebih besar dari 85 KB untuk memaksa alokasi pada tumpukan objek besar untuk mencoba dan mencegah GC merelokasi array ini. Namun, dengan diperkenalkannya generasi GC baru, Pinned Object Heap (POH), tidak masuk akal lagi untuk mengalokasikan blok pada lempengan. Kestrel sekarang langsung mengalokasikan blok pada POH, mengurangi kompleksitas yang terlibat dalam mengelola kumpulan memori. Perubahan ini harus mempermudah untuk melakukan peningkatan di masa mendatang seperti mempermudah penyusutan kumpulan memori yang digunakan oleh Kestrel.

IAsyncDisposable didukung

IAsyncDisposable sekarang tersedia untuk pengontrol, Razor Halaman, dan Komponen Tampilan. Versi asinkron telah ditambahkan ke antarmuka yang relevan di pabrik dan aktivator:

  • Metode baru menawarkan implementasi antarmuka default yang mendelegasikan ke versi sinkron dan panggilan Dispose.
  • Implementasi mengambil alih implementasi default dan menangani implementasi pembuangan IAsyncDisposable .
  • Implementasi mendukung IAsyncDisposable IDisposable ketika kedua antarmuka diimplementasikan.
  • Extender harus mengambil alih metode baru yang disertakan untuk mendukung IAsyncDisposable instans.

IAsyncDisposable bermanfaat ketika bekerja dengan:

  • Enumerator asinkron, misalnya, dalam aliran asinkron.
  • Sumber daya tidak terkelola yang memiliki operasi I/O intensif sumber daya untuk dirilis.

Saat menerapkan antarmuka ini, gunakan DisposeAsync metode untuk merilis sumber daya.

Pertimbangkan pengontrol yang membuat dan menggunakan Utf8JsonWriter. Utf8JsonWriterIAsyncDisposable adalah sumber daya:

public class HomeController : Controller, IAsyncDisposable
{
    private Utf8JsonWriter? _jsonWriter;
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
        _jsonWriter = new Utf8JsonWriter(new MemoryStream());
    }

IAsyncDisposable harus mengimplementasikan DisposeAsync:

public async ValueTask DisposeAsync()
{
    if (_jsonWriter is not null)
    {
        await _jsonWriter.DisposeAsync();
    }

    _jsonWriter = null;
}

Port Vcpkg untuk SignalR klien C++

Vcpkg adalah manajer paket baris perintah lintas platform untuk pustaka C dan C++. Kami baru-baru ini menambahkan port untuk vcpkg menambahkan CMake dukungan asli untuk SignalR klien C++. vcpkg juga berfungsi dengan MSBuild.

Klien SignalR dapat ditambahkan ke proyek CMake dengan cuplikan berikut ketika vcpkg disertakan dalam file toolchain:

find_package(microsoft-signalr CONFIG REQUIRED)
link_libraries(microsoft-signalr::microsoft-signalr)

Dengan cuplikan sebelumnya, SignalR klien C++ siap digunakan #include dan digunakan dalam proyek tanpa konfigurasi tambahan. Untuk contoh lengkap aplikasi C++ yang menggunakan SignalR klien C++, lihat repositori halter73/SignalR-Client-Cpp-Sample .

Blazor

Perubahan templat proyek

Beberapa perubahan templat proyek dilakukan untuk Blazor aplikasi, termasuk penggunaan Pages/_Layout.cshtml file untuk konten tata letak yang muncul dalam _Host.cshtml file untuk aplikasi sebelumnya Blazor Server . Pelajari perubahan dengan membuat aplikasi dari templat proyek 6.0 atau mengakses sumber referensi ASP.NET Core untuk templat proyek:

Blazor WebAssembly dukungan dependensi asli

Blazor WebAssembly aplikasi dapat menggunakan dependensi asli yang dibuat untuk berjalan di WebAssembly. Untuk informasi selengkapnya, lihat dependensi asli ASP.NET CoreBlazor WebAssembly.

Kompilasi WebAssembly Ahead-of-time (AOT) dan runtime relinking

Blazor WebAssembly mendukung kompilasi ahead-of-time (AOT), di mana Anda dapat mengkompilasi kode .NET langsung ke WebAssembly. Kompilasi AOT menghasilkan peningkatan performa runtime dengan mengorbankan ukuran aplikasi yang lebih besar. Menautkan ulang runtime .NET WebAssembly memangkas kode runtime yang tidak digunakan dan dengan demikian meningkatkan kecepatan unduhan. Untuk informasi selengkapnya, lihat Kompilasi ahead-of-time (AOT) dan Runtime relinking.

Mempertahankan status yang telah dirender sebelumnya

Blazor mendukung status bertahan di halaman yang telah dirender sebelumnya sehingga status tidak perlu dibuat ulang saat aplikasi dimuat sepenuhnya. Untuk informasi selengkapnya, lihat Merender dan mengintegrasikan komponen ASP.NET CoreRazor.

Batas kesalahan

Batas kesalahan memberikan pendekatan yang mudah untuk menangani pengecualian pada tingkat UI. Untuk informasi selengkapnya, lihat Menangani kesalahan di aplikasi ASP.NET CoreBlazor.

Dukungan SVG

Elemen <foreignObject> elemen didukung untuk menampilkan HTML arbitrer dalam SVG. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.

Blazor Server dukungan untuk transfer array byte di JS Interop

Blazor mendukung interop array JS byte yang dioptimalkan yang menghindari pengodean dan pendekodean array byte ke base64. Untuk informasi selengkapnya, lihat sumber daya berikut:

Penyempurnaan string kueri

Dukungan untuk bekerja dengan string kueri ditingkatkan. Untuk informasi selengkapnya, lihat perutean dan navigasi ASP.NET CoreBlazor.

Pengikatan untuk memilih beberapa

Pengikatan mendukung beberapa pilihan opsi dengan <input> elemen. Untuk informasi selengkapnya, lihat sumber daya berikut:

Kontrol konten head (<head>)

Razor komponen dapat mengubah konten elemen HTML <head> halaman, termasuk mengatur judul (<title> elemen) halaman dan memodifikasi metadata (<meta> elemen). Untuk informasi selengkapnya, lihat Mengontrol <head> konten di aplikasi ASP.NET CoreBlazor.

Membuat komponen Angular dan React

Hasilkan komponen JavaScript khusus kerangka kerja dari Razor komponen untuk kerangka kerja web, seperti Angular atau React. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.

Merender komponen dari JavaScript

Render Razor komponen secara dinamis dari JavaScript untuk aplikasi JavaScript yang ada. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.

Elemen kustom

Dukungan eksperimental tersedia untuk membangun elemen kustom, yang menggunakan antarmuka HTML standar. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.

Menyimpulkan jenis generik komponen dari komponen leluhur

Komponen leluhur dapat mengaitkan parameter jenis berdasarkan nama ke turunan menggunakan atribut baru [CascadingTypeParameter] . Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.

Komponen yang dirender secara dinamis

Gunakan komponen bawaan DynamicComponent baru untuk merender komponen berdasarkan jenis. Untuk informasi selengkapnya, lihat Komponen ASP.NET Core Razor yang dirender secara dinamis.

Aksesibilitas yang ditingkatkan Blazor

Gunakan komponen baru FocusOnNavigate untuk mengatur fokus UI ke elemen berdasarkan pemilih CSS setelah menavigasi dari satu halaman ke halaman lainnya. Untuk informasi selengkapnya, lihat perutean dan navigasi ASP.NET CoreBlazor.

Dukungan argumen peristiwa kustom

Blazor mendukung argumen peristiwa kustom, yang memungkinkan Anda meneruskan data arbitrer ke penanganan aktivitas .NET dengan peristiwa kustom. Untuk informasi selengkapnya, lihat penanganan peristiwa ASP.NET CoreBlazor.

Parameter yang diperlukan

Terapkan atribut baru [EditorRequired] untuk menentukan parameter komponen yang diperlukan. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.

Kolokasi file JavaScript dengan halaman, tampilan, dan komponen

Kolokasikan file JavaScript untuk halaman, tampilan, dan Razor komponen sebagai cara mudah untuk mengatur skrip di aplikasi. Untuk informasi selengkapnya, lihat ASP.NET Blazor interoperabilitas Core JavaScript (JS interop).

Penginisialisasi JavaScript

Penginisialisasi JavaScript menjalankan logika sebelum dan sesudah Blazor aplikasi dimuat. Untuk informasi selengkapnya, lihat ASP.NET Blazor interoperabilitas Core JavaScript (JS interop).

Interop Streaming JavaScript

Blazor sekarang mendukung data streaming langsung antara .NET dan JavaScript. Untuk informasi selengkapnya, lihat sumber daya berikut:

Batasan jenis generik

Parameter jenis generik sekarang didukung. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.

Tata letak penyebaran WebAssembly

Gunakan tata letak penyebaran untuk mengaktifkan Blazor WebAssembly unduhan aplikasi di lingkungan keamanan terbatas. Untuk informasi selengkapnya, lihat Tata letak penyebaran untuk aplikasi yang dihosting Blazor WebAssembly ASP.NET Core.

Artikel baru Blazor

Selain fitur yang Blazor dijelaskan di bagian sebelumnya, artikel baru Blazor tersedia pada subjek berikut:

  • ASP.NET Unduhan file CoreBlazor: Pelajari cara mengunduh file menggunakan interop streaming asli byte[] untuk memastikan transfer yang efisien ke klien.
  • Bekerja dengan gambar di ASP.NET Core Blazor: Temukan cara bekerja dengan gambar di Blazor aplikasi, termasuk cara mengalirkan data gambar dan mempratinjau gambar.

Membangun Blazor Hybrid aplikasi dengan .NET MAUI, WPF, dan Formulir Windows

Gunakan Blazor Hybrid untuk memadukan kerangka kerja klien asli desktop dan seluler dengan .NET dan Blazor:

  • .NET Multi-platform App UI (.NET MAUI) adalah kerangka kerja lintas platform untuk membuat aplikasi seluler dan desktop asli dengan C# dan XAML.
  • Blazor Hybridaplikasi dapat dibangun dengan Windows Presentation Foundation (WPF) dan kerangka kerja Formulir Windows.

Penting

Blazor Hybrid dalam pratinjau dan tidak boleh digunakan dalam aplikasi produksi hingga rilis akhir.

Untuk informasi selengkapnya, lihat sumber daya berikut:

Kestrel

HTTP/3 saat ini dalam draf dan karenanya dapat berubah. Dukungan HTTP/3 di ASP.NET Core tidak dirilis, ini adalah fitur pratinjau yang disertakan dalam .NET 6.

Kestrel sekarang mendukung HTTP/3. Untuk informasi selengkapnya, lihat Menggunakan HTTP/3 dengan server web ASP.NET Core Kestrel dan entri blog dukungan HTTP/3 di .NET 6.

Kategori pengelogan baru Kestrel untuk pengelogan yang dipilih

Sebelum perubahan ini, mengaktifkan pengelogan verbose sangat Kestrel mahal karena semua berbagi Microsoft.AspNetCore.Server.Kestrel nama kategori pengeloganKestrel. Microsoft.AspNetCore.Server.Kestrel masih tersedia, tetapi subkataan baru berikut ini memungkinkan kontrol pengelogan yang lebih banyak:

  • Microsoft.AspNetCore.Server.Kestrel(kategori saat ini): ApplicationError, , ConnectionHeadResponseBodyWrite, RequestBodyStartApplicationNeverCompleted, RequestBodyDone, , RequestBodyDrainTimedOutRequestBodyNotEntirelyRead, ResponseMinimumDataRateNotSatisfied, , InvalidResponseHeaderRemoved. HeartbeatSlow
  • Microsoft.AspNetCore.Server.Kestrel.BadRequests: ConnectionBadRequest, RequestProcessingError, . RequestBodyMinimumDataRateNotSatisfied
  • Microsoft.AspNetCore.Server.Kestrel.Connections: ConnectionAccepted, , ConnectionStart, ConnectionPauseConnectionStop, ConnectionResume, ConnectionKeepAlive, ConnectionRejected, ConnectionDisconnect, NotAllConnectionsClosedGracefully, NotAllConnectionsAborted, . ApplicationAbortedConnection
  • Microsoft.AspNetCore.Server.Kestrel.Http2: Http2ConnectionError, , Http2ConnectionClosing, Http2StreamErrorHttp2ConnectionClosed, Http2StreamResetAbort, HPackDecodingError, HPackEncodingError, Http2FrameReceived, , Http2FrameSending. Http2MaxConcurrentStreamsReached
  • Microsoft.AspNetCore.Server.Kestrel.Http3: Http3ConnectionError, , Http3ConnectionClosedHttp3ConnectionClosing, Http3StreamAbort, , Http3FrameReceived. Http3FrameSending

Aturan yang ada terus berfungsi, tetapi Anda sekarang bisa lebih selektif tentang aturan mana yang Anda aktifkan. Misalnya, overhead pengamatan mengaktifkan pengelogan Debug hanya untuk permintaan buruk sangat berkurang dan dapat diaktifkan dengan konfigurasi berikut:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.Kestrel.BadRequests": "Debug"
    }
  }

Pemfilteran log menerapkan aturan dengan awalan kategori pencocokan terpanjang. Untuk informasi selengkapnya, lihat Bagaimana aturan pemfilteran diterapkan

Memancarkan KestrelServerOptions melalui peristiwa EventSource

KestrelEventSource memancarkan peristiwa baru yang berisi JSon-serial ketika KestrelServerOptions diaktifkan dengan verbositas EventLevel.LogAlways. Kejadian ini mempermudah alasan tentang perilaku server saat menganalisis jejak yang dikumpulkan. ON berikut JSadalah contoh payload peristiwa:

{
  "AllowSynchronousIO": false,
  "AddServerHeader": true,
  "AllowAlternateSchemes": false,
  "AllowResponseHeaderCompression": true,
  "EnableAltSvc": false,
  "IsDevCertLoaded": true,
  "RequestHeaderEncodingSelector": "default",
  "ResponseHeaderEncodingSelector": "default",
  "Limits": {
    "KeepAliveTimeout": "00:02:10",
    "MaxConcurrentConnections": null,
    "MaxConcurrentUpgradedConnections": null,
    "MaxRequestBodySize": 30000000,
    "MaxRequestBufferSize": 1048576,
    "MaxRequestHeaderCount": 100,
    "MaxRequestHeadersTotalSize": 32768,
    "MaxRequestLineSize": 8192,
    "MaxResponseBufferSize": 65536,
    "MinRequestBodyDataRate": "Bytes per second: 240, Grace Period: 00:00:05",
    "MinResponseDataRate": "Bytes per second: 240, Grace Period: 00:00:05",
    "RequestHeadersTimeout": "00:00:30",
    "Http2": {
      "MaxStreamsPerConnection": 100,
      "HeaderTableSize": 4096,
      "MaxFrameSize": 16384,
      "MaxRequestHeaderFieldSize": 16384,
      "InitialConnectionWindowSize": 131072,
      "InitialStreamWindowSize": 98304,
      "KeepAlivePingDelay": "10675199.02:48:05.4775807",
      "KeepAlivePingTimeout": "00:00:20"
    },
    "Http3": {
      "HeaderTableSize": 0,
      "MaxRequestHeaderFieldSize": 16384
    }
  },
  "ListenOptions": [
    {
      "Address": "https://127.0.0.1:7030",
      "IsTls": true,
      "Protocols": "Http1AndHttp2"
    },
    {
      "Address": "https://[::1]:7030",
      "IsTls": true,
      "Protocols": "Http1AndHttp2"
    },
    {
      "Address": "http://127.0.0.1:5030",
      "IsTls": false,
      "Protocols": "Http1AndHttp2"
    },
    {
      "Address": "http://[::1]:5030",
      "IsTls": false,
      "Protocols": "Http1AndHttp2"
    }
  ]
}

Kejadian DiagnosticSource baru untuk permintaan HTTP yang ditolak

Kestrel sekarang memancarkan peristiwa baru DiagnosticSource untuk permintaan HTTP yang ditolak di lapisan server. Sebelum perubahan ini, tidak ada cara untuk mengamati permintaan yang ditolak ini. Peristiwa Microsoft.AspNetCore.Server.Kestrel.BadRequest baru DiagnosticSource berisi IBadRequestExceptionFeature yang dapat digunakan untuk mengintrospiksi alasan penolakan permintaan.

using Microsoft.AspNetCore.Http.Features;
using System.Diagnostics;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var diagnosticSource = app.Services.GetRequiredService<DiagnosticListener>();
using var badRequestListener = new BadRequestEventListener(diagnosticSource,
    (badRequestExceptionFeature) =>
{
    app.Logger.LogError(badRequestExceptionFeature.Error, "Bad request received");
});
app.MapGet("/", () => "Hello world");

app.Run();

class BadRequestEventListener : IObserver<KeyValuePair<string, object>>, IDisposable
{
    private readonly IDisposable _subscription;
    private readonly Action<IBadRequestExceptionFeature> _callback;

    public BadRequestEventListener(DiagnosticListener diagnosticListener,
                                   Action<IBadRequestExceptionFeature> callback)
    {
        _subscription = diagnosticListener.Subscribe(this!, IsEnabled);
        _callback = callback;
    }
    private static readonly Predicate<string> IsEnabled = (provider) => provider switch
    {
        "Microsoft.AspNetCore.Server.Kestrel.BadRequest" => true,
        _ => false
    };
    public void OnNext(KeyValuePair<string, object> pair)
    {
        if (pair.Value is IFeatureCollection featureCollection)
        {
            var badRequestFeature = featureCollection.Get<IBadRequestExceptionFeature>();

            if (badRequestFeature is not null)
            {
                _callback(badRequestFeature);
            }
        }
    }
    public void OnError(Exception error) { }
    public void OnCompleted() { }
    public virtual void Dispose() => _subscription.Dispose();
}

Untuk informasi selengkapnya, lihat Pengelogan dan diagnostik di Kestrel.

Membuat ConnectionContext dari Accept Socket

Yang baru SocketConnectionContextFactory memungkinkan untuk membuat ConnectionContext dari soket yang diterima. Ini memungkinkan untuk membangun berbasis IConnectionListenerFactory soket kustom tanpa kehilangan semua pekerjaan performa dan pengumpulan yang terjadi di SocketConnection.

Lihat contoh IConnectionListenerFactory kustom ini yang menunjukkan cara menggunakan ini SocketConnectionContextFactory.

Kestrel adalah profil peluncuran default untuk Visual Studio

Profil peluncuran default untuk semua proyek web dotnet baru adalah Kestrel. Memulai Kestrel secara signifikan lebih cepat dan menghasilkan pengalaman yang lebih responsif saat mengembangkan aplikasi.

IIS Express masih tersedia sebagai profil peluncuran untuk skenario seperti Autentikasi Windows atau berbagi port.

Port localhost untuk Kestrel acak

Lihat Port yang dihasilkan templat untuk Kestrel dalam dokumen ini untuk informasi selengkapnya.

Autentikasi dan otorisasi

Server autentikasi

.NET 3 hingga .NET 5 menggunakan IdentityServer4 sebagai bagian dari templat kami untuk mendukung penerbitan token JWT untuk SPA dan Blazor aplikasi. Templat sekarang menggunakan Duende Identity Server.

Jika Anda memperluas model identitas dan memperbarui proyek yang ada, Anda perlu memperbarui namespace dalam kode Anda dari IdentityServer4.IdentityServer ke Duende.IdentityServer dan mengikuti instruksi migrasinya.

Model lisensi untuk Duende Identity Server telah berubah menjadi lisensi timbal balik, yang mungkin memerlukan biaya lisensi ketika digunakan secara komersial dalam produksi. Lihat halaman Lisensi Duende untuk detail selengkapnya.

Negosiasi sertifikat klien tertunda

Pengembang sekarang dapat ikut serta menggunakan negosiasi sertifikat klien yang tertunda dengan menentukan ClientCertificateMode.DelayCertificate pada HttpsConnectionAdapterOptions. Ini hanya berfungsi dengan koneksi HTTP/1.1 karena HTTP/2 melarang negosiasi ulang sertifikat tertunda. Pemanggil API ini harus menyangga isi permintaan sebelum meminta sertifikat klien:

using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.AspNetCore.WebUtilities;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel(options =>
{
    options.ConfigureHttpsDefaults(adapterOptions =>
    {
        adapterOptions.ClientCertificateMode = ClientCertificateMode.DelayCertificate;
    });
});

var app = builder.Build();
app.Use(async (context, next) =>
{
    bool desiredState = GetDesiredState();
    // Check if your desired criteria is met
    if (desiredState)
    {
        // Buffer the request body
        context.Request.EnableBuffering();
        var body = context.Request.Body;
        await body.DrainAsync(context.RequestAborted);
        body.Position = 0;

        // Request client certificate
        var cert = await context.Connection.GetClientCertificateAsync();

        //  Disable buffering on future requests if the client doesn't provide a cert
    }
    await next(context);
});


app.MapGet("/", () => "Hello World!");
app.Run();

Cookie kedaluwarsa geser autentikasi sekarang dapat disesuaikan atau ditekan menggunakan yang baru OnCheckSlidingExpiration. Misalnya, peristiwa ini dapat digunakan oleh aplikasi satu halaman yang perlu melakukan ping server secara berkala tanpa memengaruhi sesi autentikasi.

Lain-lain

Hot Reload

Buat UI dan pembaruan kode dengan cepat untuk menjalankan aplikasi tanpa kehilangan status aplikasi untuk pengalaman pengembang yang lebih cepat dan lebih produktif menggunakan Hot Reload. Untuk informasi selengkapnya, lihat dukungan .NET Hot Reload untuk ASP.NET Core dan Perbarui kemajuan .NET Hot Reload dan Sorotan Visual Studio 2022.

Templat aplikasi halaman tunggal (SPA) yang disempurnakan

Templat proyek ASP.NET Core telah diperbarui untuk Angular dan React untuk menggunakan pola yang ditingkatkan untuk aplikasi satu halaman yang lebih fleksibel dan lebih selaras dengan pola umum untuk pengembangan web front-end modern.

Sebelumnya, templat ASP.NET Core untuk Angular dan React menggunakan middleware khusus selama pengembangan untuk meluncurkan server pengembangan untuk kerangka kerja front-end dan kemudian permintaan proksi dari ASP.NET Core ke server pengembangan. Logika untuk meluncurkan server pengembangan front-end khusus untuk antarmuka baris perintah untuk kerangka kerja front-end yang sesuai. Mendukung kerangka kerja front-end tambahan menggunakan pola ini berarti menambahkan logika tambahan ke ASP.NET Core.

Templat ASP.NET Core yang diperbarui untuk Angular dan React di .NET 6 membalikkan pengaturan ini dan memanfaatkan dukungan proksi bawaan di server pengembangan dari sebagian besar kerangka kerja front-end modern. Ketika aplikasi ASP.NET Core diluncurkan, server pengembangan front-end diluncurkan seperti sebelumnya, tetapi server pengembangan dikonfigurasi untuk memproksi permintaan ke proses backend ASP.NET Core. Semua konfigurasi khusus front-end untuk menyiapkan proksi adalah bagian dari aplikasi, bukan ASP.NET Core. Menyiapkan proyek ASP.NET Core untuk bekerja dengan kerangka kerja front-end lainnya sekarang lurus ke depan: menyiapkan server pengembangan front-end untuk kerangka kerja yang dipilih untuk diproksi ke backend ASP.NET Core menggunakan pola yang ditetapkan dalam templat Angular dan React.

Kode startup untuk aplikasi ASP.NET Core tidak lagi memerlukan logika khusus aplikasi satu halaman. Logika untuk memulai server pengembangan front-end selama pengembangan disuntikkan ke aplikasi saat runtime oleh paket Microsoft.AspNetCore.SpaProxy baru. Perutean fallback ditangani menggunakan perutean titik akhir alih-alih middleware khusus SPA.

Templat yang mengikuti pola ini masih dapat dijalankan sebagai proyek tunggal di Visual Studio atau menggunakan dotnet run dari baris perintah. Saat aplikasi diterbitkan, kode front-end di folder ClientApp dibangun dan dikumpulkan seperti sebelumnya ke akar web aplikasi host ASP.NET Core dan dilayani sebagai file statis. Skrip yang disertakan dalam templat mengonfigurasi server pengembangan front-end untuk menggunakan HTTPS menggunakan sertifikat pengembangan ASP.NET Core.

Draf dukungan HTTP/3 di .NET 6

HTTP/3 saat ini dalam draf dan karenanya dapat berubah. Dukungan HTTP/3 di ASP.NET Core tidak dirilis, ini adalah fitur pratinjau yang disertakan dalam .NET 6.

Lihat entri blog dukungan HTTP/3 di .NET 6.

Anotasi Tipe Referensi Nullable

Bagian dari kode sumber ASP.NET Core 6.0 telah menerapkan anotasi nullability.

Dengan menggunakan fitur Nullable baru di C# 8, ASP.NET Core dapat memberikan keamanan waktu kompilasi tambahan dalam penanganan jenis referensi. Misalnya, melindungi dari null pengecualian referensi. Proyek yang telah memilih untuk menggunakan anotasi nullable mungkin melihat peringatan build-time baru dari API ASP.NET Core.

Untuk mengaktifkan jenis referensi nullable, tambahkan properti berikut ke file proyek:

<PropertyGroup>
    <Nullable>enable</Nullable>
</PropertyGroup>

Untuk informasi selengkapnya, lihat Jenis nilai yang dapat diubah ke null.

Analisis Kode Sumber

Beberapa penganalisis platform kompilator .NET ditambahkan yang memeriksa kode aplikasi untuk masalah seperti konfigurasi atau urutan middleware yang salah, konflik perutean, dll. Untuk informasi selengkapnya, lihat Analisis kode di aplikasi ASP.NET Core.

Penyempurnaan templat aplikasi web

Templat aplikasi web:

  • Gunakan model hosting minimal baru.
  • Secara signifikan mengurangi jumlah file dan baris kode yang diperlukan untuk membuat aplikasi. Misalnya, aplikasi web kosong ASP.NET Core membuat satu file C# dengan empat baris kode dan merupakan aplikasi lengkap.
  • Menyaingkan Startup.cs dan Program.cs ke dalam satu Program.cs file.
  • Menggunakan pernyataan tingkat atas untuk meminimalkan kode yang diperlukan untuk aplikasi.
  • Menggunakan arahan global using untuk menghilangkan atau meminimalkan jumlah using baris pernyataan yang diperlukan.

Port yang dihasilkan templat untuk Kestrel

Port acak ditetapkan selama pembuatan proyek untuk digunakan oleh Kestrel server web. Port acak membantu meminimalkan konflik port ketika beberapa proyek dijalankan pada komputer yang sama.

Ketika proyek dibuat, port HTTP acak antara 5000-5300 dan port HTTPS acak antara 7000-7300 ditentukan dalam file yang dihasilkan Properties/launchSettings.json . Port dapat diubah dalam Properties/launchSettings.json file. Jika tidak ada port yang ditentukan, Kestrel default ke port HTTP 5000 dan HTTPS 5001. Untuk informasi selengkapnya, lihat Mengonfigurasi titik akhir untuk server web ASP.NET CoreKestrel.

Default pengelogan baru

Perubahan berikut dilakukan pada dan appsettings.json appsettings.Development.json:

- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

Perubahan dari "Microsoft": "Warning" ke menghasilkan pengelogan semua pesan informasi dari Microsoft namespace kecualiMicrosoft.AspNetCore ."Microsoft.AspNetCore": "Warning" Misalnya, Microsoft.EntityFrameworkCore sekarang dicatat di tingkat informasi.

Halaman pengecualian pengembang Middleware ditambahkan secara otomatis

Di lingkungan pengembangan, DeveloperExceptionPageMiddleware ditambahkan secara default. Tidak perlu lagi menambahkan kode berikut ke aplikasi UI web:

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

Dukungan untuk header permintaan yang dikodekan Latin1 di HttpSysServer

HttpSysServer sekarang mendukung header permintaan decoding yang dikodekan Latin1 dengan mengatur UseLatin1RequestHeaders properti ke HttpSysOptions true:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys(o => o.UseLatin1RequestHeaders = true);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Log Modul ASP.NET Core mencakup tanda waktu dan PID

Log diagnostik yang ditingkatkan ASP.NET Core Module (ANCM) for IIS (ANCM) mencakup tanda waktu dan PID dari proses yang memancarkan log. Tanda waktu pengelogan dan PID memudahkan untuk mendiagnosis masalah dengan proses yang tumpang tindih dimulai ulang di IIS ketika beberapa proses pekerja IIS berjalan.

Log yang dihasilkan sekarang menyerupai contoh output yang ditunjukkan di bawah ini:

[2021-07-28T19:23:44.076Z, PID: 11020] [aspnetcorev2.dll] Initializing logs for 'C:\<path>\aspnetcorev2.dll'. Process Id: 11020. File Version: 16.0.21209.0. Description: IIS ASP.NET Core Module V2. Commit: 96475a2acdf50d7599ba8e96583fa73efbe27912.
[2021-07-28T19:23:44.079Z, PID: 11020] [aspnetcorev2.dll] Resolving hostfxr parameters for application: '.\InProcessWebSite.exe' arguments: '' path: 'C:\Temp\e86ac4e9ced24bb6bacf1a9415e70753\'
[2021-07-28T19:23:44.080Z, PID: 11020] [aspnetcorev2.dll] Known dotnet.exe location: ''

Ukuran buffer masuk yang tidak dapat dikonfigurasi untuk IIS

Server IIS sebelumnya hanya menyangga 64 KiB badan permintaan yang tidak dikonsumsi. Buffering 64 KiB mengakibatkan pembacaan dibatasi hingga ukuran maksimum tersebut, yang berdampak pada performa dengan bodi masuk besar seperti unggahan. Di .NET 6 , ukuran buffer default berubah dari 64 KiB menjadi 1 MiB yang harus meningkatkan throughput untuk unggahan besar. Dalam pengujian kami, unggahan 700 MiB yang digunakan untuk mengambil waktu 9 detik sekarang hanya membutuhkan waktu 2,5 detik.

Kelemahan dari ukuran buffer yang lebih besar adalah peningkatan konsumsi memori per permintaan ketika aplikasi tidak dengan cepat membaca dari isi permintaan. Jadi, selain mengubah ukuran buffer default, ukuran buffer yang dapat dikonfigurasi, memungkinkan aplikasi untuk mengonfigurasi ukuran buffer berdasarkan beban kerja.

Lihat Bantuan Tag Komponen

Pertimbangkan komponen tampilan dengan parameter opsional, seperti yang ditunjukkan dalam kode berikut:

class MyViewComponent
{
    IViewComponentResult Invoke(bool showSomething = false) { ... }
}

Dengan ASP.NET Core 6, pembantu tag dapat dipanggil tanpa harus menentukan nilai untuk showSomething parameter:

<vc:my />

Templat Angular diperbarui ke Angular 12

Templat ASP.NET Core 6.0 untuk Angular sekarang menggunakan Angular 12.

Templat React telah diperbarui ke React 17.

Ambang buffer yang dapat dikonfigurasi sebelum menulis ke disk dalam formatter output Json.NET

Catatan: Sebaiknya gunakan System.Text.Json pemformat output kecuali saat Newtonsoft.Json serializer diperlukan karena alasan kompatibilitas. Serializer System.Text.Json sepenuhnya async dan berfungsi secara efisien untuk payload yang lebih besar.

Formatter Newtonsoft.Json output secara default buffer merespons hingga 32 KiB dalam memori sebelum buffering ke disk. Ini untuk menghindari melakukan IO sinkron, yang dapat mengakibatkan efek samping lainnya seperti kelaparan utas dan kebuntuan aplikasi. Namun, jika respons lebih besar dari 32 KiB, I/O disk yang cukup besar terjadi. Ambang memori sekarang dapat dikonfigurasi melalui properti MvcNewtonsoftJsonOptions.OutputFormatterMemoryBufferThreshold sebelum buffering ke disk:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages()
            .AddNewtonsoftJson(options =>
            { 
                options.OutputFormatterMemoryBufferThreshold = 48 * 1024;
            });

var app = builder.Build();

Untuk informasi selengkapnya, lihat permintaan pull GitHub ini dan file NewtonsoftJsonOutputFormatterTest.cs .

Dapatkan dan atur lebih cepat untuk header HTTP

API baru ditambahkan untuk mengekspos semua header umum yang tersedia sebagai Microsoft.Net.Http.Headers.HeaderNames properti yang IHeaderDictionary menghasilkan API yang lebih mudah digunakan. Misalnya, middleware sebaris dalam kode berikut mendapatkan dan mengatur header permintaan dan respons menggunakan API baru:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Use(async (context, next) =>
{
    var hostHeader = context.Request.Headers.Host;
    app.Logger.LogInformation("Host header: {host}", hostHeader);
    context.Response.Headers.XPoweredBy = "ASP.NET Core 6.0";
    await next.Invoke(context);
    var dateHeader = context.Response.Headers.Date;
    app.Logger.LogInformation("Response date: {date}", dateHeader);
});

app.Run();

Untuk header yang diimplementasikan, aksesor dapatkan dan atur diimplementasikan dengan langsung ke bidang dan melewati pencarian. Untuk header yang tidak diimplementasikan, pengakses dapat melewati pencarian awal terhadap header yang diimplementasikan dan langsung melakukan Dictionary<string, StringValues> pencarian. Menghindari pencarian menghasilkan akses yang lebih cepat untuk kedua skenario.

Streaming asinkron

ASP.NET Core sekarang mendukung streaming asinkron dari tindakan pengontrol dan respons dari JSformatter ON. Mengembalikan IAsyncEnumerable dari tindakan tidak lagi menyangga konten respons dalam memori sebelum dikirim. Tidak buffering membantu mengurangi penggunaan memori saat mengembalikan himpunan data besar yang dapat dijumlahkan secara asinkron.

Perhatikan bahwa Entity Framework Core menyediakan implementasi untuk mengkueri IAsyncEnumerable database. Dukungan yang ditingkatkan untuk IAsyncEnumerable di ASP.NET Core di .NET 6 dapat membuat penggunaan EF Core dengan ASP.NET Core lebih efisien. Misalnya, kode berikut tidak lagi menyangga data produk ke dalam memori sebelum mengirim respons:

public IActionResult GetMovies()
{
    return Ok(_context.Movie);
}

Namun, saat menggunakan pemuatan malas di EF Core, perilaku baru ini dapat mengakibatkan kesalahan karena eksekusi kueri bersamaan saat data sedang dijumlahkan. Aplikasi dapat kembali ke perilaku sebelumnya dengan menyangga data:

public async Task<IActionResult> GetMovies2()
{
    return Ok(await _context.Movie.ToListAsync());
}

Lihat pengumuman terkait untuk detail tambahan tentang perubahan perilaku ini.

Middleware pengelogan HTTP

Pengelogan HTTP adalah middleware bawaan baru yang mencatat informasi tentang permintaan HTTP dan respons HTTP termasuk header dan seluruh isi:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();
app.UseHttpLogging();

app.MapGet("/", () => "Hello World!");

app.Run();

Menavigasi ke / dengan informasi log kode sebelumnya yang mirip dengan output berikut:

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
      Request:
      Protocol: HTTP/2
      Method: GET
      Scheme: https
      PathBase: 
      Path: /
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-US,en;q=0.9
      Cache-Control: max-age=0
      Connection: close
      Cookie: [Redacted]
      Host: localhost:44372
      User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30
      sec-ch-ua: [Redacted]
      sec-ch-ua-mobile: [Redacted]
      sec-ch-ua-platform: [Redacted]
      upgrade-insecure-requests: [Redacted]
      sec-fetch-site: [Redacted]
      sec-fetch-mode: [Redacted]
      sec-fetch-user: [Redacted]
      sec-fetch-dest: [Redacted]
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
      Response:
      StatusCode: 200
      Content-Type: text/plain; charset=utf-8

Output sebelumnya diaktifkan dengan file berikut appsettings.Development.json :

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
    }
  }
}

Pengelogan HTTP menyediakan log dari:

  • Informasi Permintaan HTTP
  • Properti umum
  • Header
  • Isi
  • Informasi Respons HTTP

Untuk mengonfigurasi middleware pengelogan HTTP, tentukan HttpLoggingOptions:

using Microsoft.AspNetCore.HttpLogging;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
    // Customize HTTP logging.
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add("My-Request-Header");
    logging.ResponseHeaders.Add("My-Response-Header");
    logging.MediaTypeOptions.AddText("application/javascript");
    logging.RequestBodyLogLimit = 4096;
    logging.ResponseBodyLogLimit = 4096;
});

var app = builder.Build();
app.UseHttpLogging();

app.MapGet("/", () => "Hello World!");

app.Run();

IConnectionSocketFeature

IConnectionSocketFeature Fitur permintaan menyediakan akses ke soket terima yang mendasar yang terkait dengan permintaan saat ini. Ini dapat diakses melalui on FeatureCollection HttpContext.

Misalnya, aplikasi berikut mengatur LingerState properti pada soket yang diterima:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions => listenOptions.Use((connection, next) =>
    {
        var socketFeature = connection.Features.Get<IConnectionSocketFeature>();
        socketFeature.Socket.LingerState = new LingerOption(true, seconds: 10);
        return next();
    }));
});
var app = builder.Build();
app.MapGet("/", (Func<string>)(() => "Hello world"));
await app.RunAsync();

Batasan jenis generik dalam Razor

Saat menentukan parameter jenis generik dalam Razor menggunakan @typeparam direktif, batasan jenis generik sekarang dapat ditentukan menggunakan sintaks C# standar:

Skrip MessagePack yang lebih SignalRkecil , Blazor Server, dan

SignalRSkrip , MessagePack, dan Blazor Server sekarang secara signifikan lebih kecil, memungkinkan unduhan yang lebih kecil, penguraian dan kompilasi JavaScript yang lebih sedikit oleh browser, dan start-up yang lebih cepat. Pengurangan ukuran:

  • signalr.js: 70%
  • blazor.server.js: 45%

Skrip yang lebih kecil adalah hasil dari kontribusi komunitas dari Ben Adams. Untuk informasi selengkapnya tentang detail pengurangan ukuran, lihat Permintaan penarikan GitHub Ben.

Mengaktifkan sesi pembuatan profil Redis

Kontribusi komunitas dari Gabriel Lucaci memungkinkan sesi pembuatan profil Redis dengan Microsoft.Extensions.Caching.StackExchangeRedis:

using StackExchange.Redis.Profiling;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.ProfilingSession = () => new ProfilingSession();
});

Untuk informasi selengkapnya, lihat Pembuatan Profil StackExchange.Redis.

Penyalinan bayangan di IIS

Fitur eksperimental telah ditambahkan ke ASP.NET Core Module (ANCM) untuk IIS guna menambahkan dukungan untuk rakitan aplikasi penyalinan bayangan. Saat ini .NET mengunci biner aplikasi saat berjalan di Windows sehingga tidak mungkin mengganti biner saat aplikasi berjalan. Meskipun rekomendasi kami tetap menggunakan file offline aplikasi, kami menyadari ada skenario tertentu (misalnya penyebaran FTP) di mana tidak dimungkinkan untuk melakukannya.

Dalam skenario seperti itu, aktifkan penyalinan bayangan dengan menyesuaikan pengaturan handler modul ASP.NET Core. Dalam kebanyakan kasus, aplikasi ASP.NET Core tidak memiliki web.config kontrol sumber yang dapat Anda ubah. Dalam ASP.NET Core, web.config biasanya dihasilkan oleh SDK. Sampel web.config berikut dapat digunakan untuk memulai:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- To customize the asp.net core module uncomment and edit the following section. 
  For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->

  <system.webServer>
    <handlers>
      <remove name="aspNetCore"/>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
      <handlerSettings>
        <handlerSetting name="experimentalEnableShadowCopy" value="true" />
        <handlerSetting name="shadowCopyDirectory" value="../ShadowCopyDirectory/" />
        <!-- Only enable handler logging if you encounter issues-->
        <!--<handlerSetting name="debugFile" value=".\logs\aspnetcore-debug.log" />-->
        <!--<handlerSetting name="debugLevel" value="FILE,TRACE" />-->
      </handlerSettings>
    </aspNetCore>
  </system.webServer>
</configuration>

Penyalinan bayangan di IIS adalah fitur eksperimental yang tidak dijamin menjadi bagian dari ASP.NET Core. Silakan tinggalkan umpan balik tentang penyalinan Bayangan IIS dalam masalah GitHub ini.

Sumber Daya Tambahan: