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

Halaman MVC dan Razor

Dukungan untuk model nullable dalam tampilan MVC dan Razor Pages

Halaman atau model tampilan yang dapat dibatalkan didukung untuk meningkatkan pengalaman saat menggunakan pemeriksaan status nol dengan aplikasi ASP.NET Core:

@model Product?

Ikat dengan IParsable<T>.TryParse di MVC dan Pengontrol API

Itu IParsable<TSelf>.TryParse API mendukung nilai parameter tindakan pengontrol yang mengikat. Untuk informasi lebih lanjut, lihat Mengikat dengan IParsable<T>.TryParse.

Dalam versi ASP.NET Core yang lebih lama dari 7, validasi persetujuan cookie menggunakan nilai cookie yes untuk menunjukkan persetujuan. Sekarang Anda dapat menentukan nilai yang mewakili persetujuan. Misalnya, Anda dapat menggunakan true dari pada yes:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure<CookiePolicyOptions>(options =>

    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
    options.ConsentCookieValue = "true";
);

var app = builder.Build();

Untuk informasi selengkapnya, lihat Menyesuaikan nilai izin cookie.

Pengontrol API

Pengikatan parameter dengan DI di pengontrol API

Pengikatan parameter untuk tindakan pengontrol API mengikat parameter melalui injeksi ketergantungan saat jenis dikonfigurasi sebagai layanan. Ini berarti tidak lagi diperlukan untuk secara eksplisit menerapkan [FromServices] atribut ke parameter. Dalam kode berikut, kedua tindakan mengembalikan waktu:

[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase

    public ActionResult GetWithAttribute([FromServices] IDateTime dateTime) 
                                                        => Ok(dateTime.Now);

    [Route("noAttribute")]
    public ActionResult Get(IDateTime dateTime) => Ok(dateTime.Now);

Dalam kasus yang jarang terjadi, DI otomatis dapat merusak aplikasi yang memiliki tipe DI yang juga diterima dalam metode tindakan pengontrol API. Ini tidak umum untuk memiliki tipe DI dan sebagai argumen dalam tindakan pengontrol API. Untuk menonaktifkan pengikatan parameter secara otomatis, setel DisableImplicitFromServicesParameters

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddSingleton<IDateTime, SystemDateTime>();

builder.Services.Configure<ApiBehaviorOptions>(options =>

    options.DisableImplicitFromServicesParameters = true;
);

var app = builder.Build();

app.MapControllers();

app.Run();

Di ASP.NET Core 7.0, jenis DI diperiksa saat memulai aplikasi dengan IServiceProviderIsService untuk menentukan apakah argumen dalam tindakan pengontrol API berasal dari DI atau dari sumber lain.

Mekanisme baru untuk menyimpulkan sumber pengikatan parameter tindakan Pengontrol API menggunakan aturan berikut:

  1. Yang ditentukan sebelumnya BindingInfo.BindingSource tidak pernah ditimpa.
  2. Parameter tipe kompleks, terdaftar di wadah DI, ditetapkan BindingSource.Services.
  3. Parameter tipe kompleks, tidak terdaftar di wadah DI, ditetapkan BindingSource.Body.
  4. Parameter dengan nama yang muncul sebagai nilai rute di setiap template rute ditetapkan BindingSource.Path.
  5. Semua parameter lainnya adalah BindingSource.Query.

Nama properti JSON dalam kesalahan validasi

Secara default, ketika kesalahan validasi terjadi, validasi model menghasilkan ModelStateDictionary dengan nama properti sebagai kunci kesalahan. Beberapa aplikasi, seperti aplikasi satu halaman, mendapat manfaat dari penggunaan nama properti JSON untuk kesalahan validasi yang dihasilkan dari Web API. Kode berikut mengonfigurasi validasi untuk menggunakan SystemTextJsonValidationMetadataProvider untuk menggunakan nama properti JSON:

using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>

    options.ModelMetadataDetailsProviders.Add(new SystemTextJsonValidationMetadataProvider());
);

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Kode berikut mengonfigurasi validasi untuk menggunakan NewtonsoftJsonValidationMetadataProvider untuk menggunakan nama properti JSON saat menggunakan Json.NET:

using Microsoft.AspNetCore.Mvc.NewtonsoftJson;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>

    options.ModelMetadataDetailsProviders.Add(new NewtonsoftJsonValidationMetadataProvider());
).AddNewtonsoftJson();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Untuk informasi selengkapnya, lihat Menggunakan nama properti JSON dalam kesalahan validasi

API minimal

Filter di aplikasi API Minimal

Filter API minimal memungkinkan pengembang menerapkan logika bisnis yang mendukung:

  • Menjalankan kode sebelum dan sesudah penangan rute.
  • Memeriksa dan memodifikasi parameter yang disediakan selama pemanggilan pengendali rute.
  • Mencegat perilaku respons penangan rute.

Filter dapat membantu dalam skenario berikut:

  • Memvalidasi parameter permintaan dan isi yang dikirim ke titik akhir.
  • Mencatat informasi tentang permintaan dan tanggapan.
  • Memvalidasi bahwa permintaan menargetkan versi API yang didukung.

Untuk informasi lebih lanjut, lihat Filter di aplikasi API Minimal

Ikat array dan nilai string dari header dan string kueri

Di ASP.NET 7, mengikat string kueri ke array tipe primitif, array string, dan StringValues ​​didukung:

// Bind query string values to a primitive type array.
// GET  /tags?q=1&q=2&q=3
app.MapGet("/tags", (int[] q) =>
                      $"tag1: q[0] , tag2: q[1], tag3: q[2]");

// Bind to a string array.
// GET /tags2?names=john&names=jack&names=jane
app.MapGet("/tags2", (string[] names) =>
            $"tag1: names[0] , tag2: names[1], tag3: names[2]");

// Bind to StringValues.
// GET /tags3?names=john&names=jack&names=jane
app.MapGet("/tags3", (StringValues names) =>
            $"tag1: names[0] , tag2: names[1], tag3: names[2]");

Mengikat string kueri atau nilai header ke array tipe kompleks didukung saat tipe memiliki TryParse dilaksanakan. Untuk informasi selengkapnya, lihat mengikat array dan nilai string dari header dan string kueri.

Berikan deskripsi dan ringkasan titik akhir

API Minimal sekarang mendukung operasi anotasi dengan deskripsi dan ringkasan untuk pembuatan spesifikasi OpenAPI. Anda dapat memanggil metode ekstensi WithDescription dan WithSummary atau menggunakan atribut [EndpointDescription] dan [EndpointSummary]).

Untuk informasi selengkapnya, lihat Menambahkan ringkasan atau deskripsi titik akhir.

Ikat badan permintaan sebagai Stream atau PipeReader

Badan permintaan dapat mengikat sebagai Stream atau PipeReader untuk secara efisien mendukung skenario di mana pengguna harus memproses data dan:

  • Simpan data ke penyimpanan gumpalan atau enqueue data ke penyedia antrian.
  • Memproses data yang disimpan dengan proses pekerja atau fungsi cloud.

Misalnya, data mungkin diantrekan ke penyimpanan Azure Queue atau disimpan di penyimpanan Azure Blob.

Kode berikut mengimplementasikan antrian latar belakang:

using System.Text.Json;
using System.Threading.Channels;

namespace BackgroundQueueService;

class BackgroundQueue : BackgroundService
{
    private readonly Channel<ReadOnlyMemory<byte>> _queue;
    private readonly ILogger<BackgroundQueue> _logger;

    public BackgroundQueue(Channel<ReadOnlyMemory<byte>> queue,
                               ILogger<BackgroundQueue> logger)
    
        _queue = queue;
        _logger = logger;
    

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    
        await foreach (var dataStream in _queue.Reader.ReadAllAsync(stoppingToken))
        
            try
            
                var person = JsonSerializer.Deserialize<Person>(dataStream.Span)!;
                _logger.LogInformation($"person.Name is person.Age " +
                                       $"years and from person.Country");
            
            catch (Exception ex)
            
                _logger.LogError(ex.Message);
            
        
    
}

class Person

    public string Name  get; set;  = String.Empty;
    public int Age  get; set; 
    public string Country  get; set;  = String.Empty;

Kode berikut mengikat badan permintaan ke a Stream:

app.MapPost("/register", async (HttpRequest req, Stream body,
                                 Channel<ReadOnlyMemory<byte>> queue) =>

    if (req.ContentLength is not null && req.ContentLength > maxMessageSize)
    
        return Results.BadRequest();
    

    // We're not above the message size and we have a content length, or
    // we're a chunked request and we're going to read up to the maxMessageSize + 1. 
    // We add one to the message size so that we can detect when a chunked request body
    // is bigger than our configured max.
    var readSize = (int?)req.ContentLength ?? (maxMessageSize + 1);

    var buffer = new byte[readSize];

    // Read at least that many bytes from the body.
    var read = await body.ReadAtLeastAsync(buffer, readSize, throwOnEndOfStream: false);

    // We read more than the max, so this is a bad request.
    if (read > maxMessageSize)
    
        return Results.BadRequest();
    

    // Attempt to send the buffer to the background queue.
    if (queue.Writer.TryWrite(buffer.AsMemory(0..read)))
    
        return Results.Accepted();
    

    // We couldn't accept the message since we're overloaded.
    return Results.StatusCode(StatusCodes.Status429TooManyRequests);
);

Kode berikut menunjukkan yang lengkap Program.cs mengajukan:

using System.Threading.Channels;
using BackgroundQueueService;

var builder = WebApplication.CreateBuilder(args);
// The max memory to use for the upload endpoint on this instance.
var maxMemory = 500 * 1024 * 1024;

// The max size of a single message, staying below the default LOH size of 85K.
var maxMessageSize = 80 * 1024;

// The max size of the queue based on those restrictions
var maxQueueSize = maxMemory / maxMessageSize;

// Create a channel to send data to the background queue.
builder.Services.AddSingleton<Channel<ReadOnlyMemory<byte>>>((_) =>
                     Channel.CreateBounded<ReadOnlyMemory<byte>>(maxQueueSize));

// Create a background queue service.
builder.Services.AddHostedService<BackgroundQueue>();
var app = builder.Build();

// curl --request POST 'https://localhost:<port>/register' --header 'Content-Type: application/json' --data-raw ' "Name":"Samson", "Age": 23, "Country":"Nigeria" '
// curl --request POST "https://localhost:<port>/register" --header "Content-Type: application/json" --data-raw " \"Name\":\"Samson\", \"Age\": 23, \"Country\":\"Nigeria\" "
app.MapPost("/register", async (HttpRequest req, Stream body,
                                 Channel<ReadOnlyMemory<byte>> queue) =>

    if (req.ContentLength is not null && req.ContentLength > maxMessageSize)
    
        return Results.BadRequest();
    

    // We're not above the message size and we have a content length, or
    // we're a chunked request and we're going to read up to the maxMessageSize + 1. 
    // We add one to the message size so that we can detect when a chunked request body
    // is bigger than our configured max.
    var readSize = (int?)req.ContentLength ?? (maxMessageSize + 1);

    var buffer = new byte[readSize];

    // Read at least that many bytes from the body.
    var read = await body.ReadAtLeastAsync(buffer, readSize, throwOnEndOfStream: false);

    // We read more than the max, so this is a bad request.
    if (read > maxMessageSize)
    
        return Results.BadRequest();
    

    // Attempt to send the buffer to the background queue.
    if (queue.Writer.TryWrite(buffer.AsMemory(0..read)))
    
        return Results.Accepted();
    

    // We couldn't accept the message since we're overloaded.
    return Results.StatusCode(StatusCodes.Status429TooManyRequests);
);

app.Run();

Batasan saat mengikat badan permintaan ke Stream atau PipeReader:

  • Saat membaca data, Stream adalah objek yang sama dengan HttpRequest.Body.
  • Badan permintaan tidak disangga secara default. Setelah tubuh dibaca, itu tidak dapat diputar ulang. Aliran tidak dapat dibaca beberapa kali.
  • Itu Stream dan PipeReader tidak dapat digunakan di luar penangan tindakan minimal karena buffer yang mendasarinya akan dibuang atau digunakan kembali.

Hasil Baru. Aliran berlebih

Kami memperkenalkan yang baru Results.Stream kelebihan beban untuk mengakomodasi skenario yang memerlukan akses ke aliran respons HTTP yang mendasarinya tanpa buffering. Kelebihan beban ini juga meningkatkan kasus di mana API mengalirkan data ke aliran respons HTTP, seperti dari Azure Blob Storage. Contoh berikut menggunakan ImageSharp untuk mengembalikan ukuran yang diperkecil dari gambar yang ditentukan:

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/process-image/strImage", (string strImage, HttpContext http, CancellationToken token) =>

    http.Response.Headers.CacheControl = $"public,max-age=TimeSpan.FromHours(24).TotalSeconds";
    return Results.Stream(stream => ResizeImageAsync(strImage, stream, token), "image/jpeg");
);

async Task ResizeImageAsync(string strImage, Stream stream, CancellationToken token)

    var strPath = $"wwwroot/img/strImage";
    using var image = await Image.LoadAsync(strPath, token);
    int width = image.Width / 2;
    int height = image.Height / 2;
    image.Mutate(x =>x.Resize(width, height));
    await image.SaveAsync(stream, JpegFormat.Instance, cancellationToken: token);

Untuk informasi lebih lanjut, lihat Contoh aliran

Hasil yang diketik untuk API minimal

Di .NET 6, antarmuka IResult diperkenalkan untuk mewakili nilai yang dikembalikan dari API minimal yang tidak menggunakan dukungan implisit untuk JSON membuat serial objek yang dikembalikan ke respons HTTP. Kelas Hasil statis digunakan untuk membuat variasi IResult objek yang mewakili berbagai jenis tanggapan. Misalnya, mengatur kode status respons atau mengarahkan ke URL lain. Itu IResult mengimplementasikan jenis kerangka kerja yang dikembalikan dari metode ini bersifat internal, sehingga sulit untuk memverifikasi spesifikasinya IResult tipe dikembalikan dari metode dalam unit test.

Di .NET 7 tipe yang diimplementasikan IResult bersifat publik, memungkinkan untuk jenis pernyataan saat pengujian. Sebagai contoh:

[TestClass()]
public class WeatherApiTests

    [TestMethod()]
    public void MapWeatherApiTest()
    
        var result = WeatherApi.GetAllWeathers();
        Assert.IsInstanceOfType(result, typeof(Ok<WeatherForecast[]>));
          

Peningkatan OpenAPI untuk API minimal

Microsoft.AspNetCore.OpenApi Paket NuGet

Itu Microsoft.AspNetCore.OpenApi package memungkinkan interaksi dengan spesifikasi OpenAPI untuk titik akhir. Paket tersebut bertindak sebagai penghubung antara model OpenAPI yang didefinisikan di Microsoft.AspNetCore.OpenApi paket dan titik akhir yang ditentukan dalam API Minimal. Paket tersebut menyediakan API yang memeriksa parameter, respons, dan metadata titik akhir untuk menyusun jenis anotasi OpenAPI yang digunakan untuk mendeskripsikan titik akhir.

app.MapPost("/todoitems/id", async (int id, Todo todo, TodoDb db) =>

    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/todo.Id", todo);
)
.WithOpenApi();

Panggilan WithOpenApi dengan parameter

Itu WithOpenApi metode menerima fungsi yang dapat digunakan untuk memodifikasi anotasi OpenAPI. Misalnya, dalam kode berikut, deskripsi ditambahkan ke parameter pertama titik akhir:

app.MapPost("/todo2/id", async (int id, Todo todo, TodoDb db) =>

    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/todo.Id", todo);
)
.WithOpenApi(generatedOperation =>

    var parameter = generatedOperation.Parameters[0];
    parameter.Description = "The ID associated with the created Todo";
    return generatedOperation;
);

Kecualikan deskripsi Open API

Dalam contoh berikut, /skipme endpoint dikecualikan dari menghasilkan deskripsi OpenAPI:

using Microsoft.AspNetCore.OpenApi;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())

    app.UseSwagger();
    app.UseSwaggerUI();


app.UseHttpsRedirection();

app.MapGet("/swag", () => "Hello Swagger!")
    .WithOpenApi();
app.MapGet("/skipme", () => "Skipping Swagger.")
                    .ExcludeFromDescription();

app.Run();

gRPC

Transkode JSON

Transcoding JSON gRPC adalah ekstensi untuk ASP.NET Core yang membuat RESTful JSON API untuk layanan gRPC. Transkode gRPC JSON memungkinkan:

  • Aplikasi untuk memanggil layanan gRPC dengan konsep HTTP yang sudah dikenal.
  • Aplikasi gRPC Inti ASP.NET untuk mendukung API gRPC dan JSON RESTful tanpa mereplikasi fungsionalitas.

Untuk informasi lebih lanjut, lihat transcoding JSON gRPC di aplikasi gRPC ASP.NET Core

SinyalR

Hasil klien

Server sekarang mendukung permintaan hasil dari klien. Ini membutuhkan server untuk digunakan ISingleClientProxy.InvokeAsync dan klien untuk mengembalikan hasil darinya .On pawang Hub yang sangat diketik juga dapat mengembalikan nilai dari metode antarmuka.

Untuk informasi lebih lanjut, lihat hasil Klien

Injeksi ketergantungan untuk metode hub SignalR

Metode hub SignalR sekarang mendukung layanan injeksi melalui injeksi ketergantungan (DI).

Konstruktor hub dapat menerima layanan dari DI sebagai parameter, yang dapat disimpan dalam properti di kelas untuk digunakan dalam metode hub. Untuk informasi lebih lanjut, lihat Menyuntikkan layanan ke hub

Pertunjukan

Peningkatan kinerja HTTP/2

.NET 7 memperkenalkan arsitektur ulang yang signifikan tentang bagaimana Kestrel memproses permintaan HTTP/2. Aplikasi ASP.NET Core dengan koneksi HTTP/2 yang sibuk akan mengalami pengurangan penggunaan CPU dan throughput yang lebih tinggi.

Sebelumnya, implementasi multiplexing HTTP/2 mengandalkan penguncian yang mengontrol permintaan mana yang dapat menulis ke koneksi TCP yang mendasarinya. Antrian thread-safe menggantikan kunci tulis. Sekarang, daripada memperebutkan utas mana yang dapat menggunakan kunci tulis, permintaan sekarang mengantre dan konsumen khusus memprosesnya. Sumber daya CPU yang sebelumnya terbuang tersedia untuk aplikasi lainnya.

Satu tempat di mana peningkatan ini dapat diperhatikan adalah di gRPC, kerangka kerja RPC populer yang menggunakan HTTP/2. Tolok ukur Kestrel + gRPC menunjukkan peningkatan dramatis:

Peningkatan kinerja Kestrel pada mesin inti tinggi

Kestrel menggunakan ConcurrentQueue untuk banyak tujuan. Salah satu tujuannya adalah menjadwalkan operasi I/O dalam transport Socket default Kestrel. Mempartisi ConcurrentQueue berdasarkan soket terkait mengurangi pertengkaran dan meningkatkan throughput pada mesin dengan banyak inti CPU.

Pembuatan profil pada mesin inti tinggi di .NET 6 menunjukkan pertentangan yang signifikan di salah satu mesin Kestrel lainnya ConcurrentQueue contoh, PinnedMemoryPool yang digunakan Kestrel untuk menyimpan buffer byte.

Di .NET 7, kumpulan memori Kestrel dipartisi dengan cara yang sama seperti antrian I/O-nya, yang mengarah ke pertentangan yang jauh lebih rendah dan throughput yang lebih tinggi pada mesin inti tinggi. Pada 80 VM ARM64 inti, kami melihat peningkatan lebih dari 500% dalam respons per detik (RPS) dalam tolok ukur teks biasa TechEmpower. Pada 48 Core AMD VM, peningkatannya hampir 100% dalam benchmark HTTPS JSON kami.

Server

Acara ServerReady baru untuk mengukur waktu startup

Itu ServerReady event telah ditambahkan untuk mengukur waktu startup aplikasi ASP.NET Core.

IIS

Penyalinan bayangan di IIS

Rakitan aplikasi penyalinan bayangan ke ASP.NET Core Module (ANCM) untuk IIS dapat memberikan pengalaman pengguna akhir yang lebih baik daripada menghentikan aplikasi dengan menyebarkan file offline aplikasi.

Untuk informasi lebih lanjut, lihat Penyalinan bayangan di IIS

Aneka ragam

jam tangan dotnet

Output konsol yang ditingkatkan untuk jam tangan dotnet

Keluaran konsol dari jam tangan dotnet telah ditingkatkan agar lebih selaras dengan pencatatan ASP.NET Core dan menonjol dengan emoji😍.

Berikut ini contoh tampilan keluaran baru:

keluaran untuk jam tangan dotnet

Lihat permintaan tarik GitHub ini untuk informasi lebih lanjut.

Konfigurasikan jam tangan dotnet untuk selalu memulai ulang untuk pengeditan kasar

Pengeditan kasar adalah pengeditan yang tidak dapat dimuat ulang. Untuk mengonfigurasi jam tangan dotnet agar selalu memulai ulang tanpa meminta pengeditan kasar, atur tombol DOTNET_WATCH_RESTART_ON_RUDE_EDIT variabel lingkungan menjadi true.

Mode gelap halaman pengecualian pengembang

Dukungan mode gelap telah ditambahkan ke halaman pengecualian pengembang, berkat kontribusi dari Patrick Westerhoff. Untuk menguji mode gelap di browser, dari halaman alat pengembang, setel mode ke gelap. Misalnya, di Firefox:

Alat F12 FF mode gelap

Di Chrome:

Alat F12 Mode gelap Chrome

Opsi templat proyek untuk menggunakan metode Program.Main alih-alih pernyataan tingkat atas

Template .NET 7 menyertakan opsi untuk tidak menggunakan pernyataan tingkat atas dan menghasilkan a namespace dan Main metode yang dideklarasikan pada a Program kelas.

Menggunakan .NET CLI, gunakan --use-program-main pilihan:

dotnet new web --use-program-main

Dengan Visual Studio, pilih yang baru Jangan gunakan pernyataan tingkat atas kotak centang selama pembuatan proyek:

kotak centang

Template Angular dan React yang diperbarui

Template proyek Angular telah diperbarui ke Angular 14. Template proyek React telah diperbarui ke React 18.2.

Kelola Token Web JSON dalam pengembangan dengan dotnet user-jwts

Yang baru dotnet user-jwts alat baris perintah dapat membuat dan mengelola Token Web JSON (JWT) lokal khusus aplikasi. Untuk informasi lebih lanjut, lihat Mengelola Token Web JSON dalam pengembangan dengan dotnet user-jwts.

Dukungan untuk header permintaan tambahan di W3CLogger

Anda sekarang dapat menentukan header permintaan tambahan untuk dicatat saat menggunakan pencatat W3C dengan menelepon AdditionalRequestHeaders() di W3CLoggerOptions:

services.AddW3CLogging(logging =>

    logging.AdditionalRequestHeaders.Add("x-forwarded-for");
    logging.AdditionalRequestHeaders.Add("x-client-ssl-protocol");
);

Untuk informasi lebih lanjut, lihat opsi W3CLogger.

Minta dekompresi

Middleware dekompresi Permintaan baru:

  • Mengaktifkan titik akhir API untuk menerima permintaan dengan konten terkompresi.
  • Menggunakan Content-Encoding Header HTTP untuk secara otomatis mengidentifikasi dan mendekompresi permintaan yang berisi konten terkompresi.
  • Menghilangkan kebutuhan untuk menulis kode untuk menangani permintaan terkompresi.

Untuk informasi selengkapnya, lihat Meminta middleware dekompresi.

By AKDSEO