Apa yang baru dalam ASP.NET Core 7.0
Artikel ini menyoroti perubahan paling signifikan dalam ASP.NET Core 7.0 dengan tautan ke dokumentasi yang relevan.
Middleware pembatasan laju di ASP.NET Core
Middleware Microsoft.AspNetCore.RateLimiting
menyediakan middleware pembatasan laju. Aplikasi mengonfigurasi kebijakan pembatasan tarif lalu melampirkan kebijakan ke titik akhir. Untuk informasi selengkapnya, lihat Middleware pembatasan laju di ASP.NET Core.
Autentikasi menggunakan skema tunggal sebagai DefaultScheme
Sebagai bagian dari pekerjaan untuk menyederhanakan autentikasi, ketika hanya ada satu skema autentikasi yang terdaftar, secara otomatis digunakan sebagai DefaultScheme dan tidak perlu ditentukan. Untuk informasi selengkapnya, lihat DefaultScheme.
MVC dan Razor halaman
Dukungan untuk model nullable dalam tampilan MVC dan Razor Pages
Model halaman atau tampilan nullable didukung untuk meningkatkan pengalaman saat menggunakan pemeriksaan status null dengan aplikasi ASP.NET Core:
@model Product?
Ikat dengan IParsable<T>.TryParse
di Pengontrol MVC dan API
IParsable<TSelf>.TryParse
API mendukung nilai parameter tindakan pengikatan pengontrol. Untuk informasi selengkapnya, lihat Mengikat dengan IParsable<T>.TryParse
.
Mengkustomisasi cookie nilai persetujuan
Dalam versi ASP.NET Core yang lebih lama dari 7, cookie validasi persetujuan menggunakan cookie nilai yes
untuk menunjukkan persetujuan. Sekarang Anda dapat menentukan nilai yang mewakili persetujuan. Misalnya, Anda dapat menggunakan true
alih-alih 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 cookie nilai persetujuan.
Pengontrol API
Pengikatan parameter dengan DI di pengontrol API
Pengikatan parameter untuk tindakan pengontrol API mengikat parameter melalui injeksi dependensi saat jenis dikonfigurasi sebagai layanan. Ini berarti tidak lagi diperlukan untuk menerapkan [FromServices]
atribut secara eksplisit 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 memutus aplikasi yang memiliki jenis di DI yang juga diterima dalam metode tindakan pengontrol API. Memiliki suatu jenis dalam DI dan sebagai suatu argumen di tindakan pengontrol API bukanlah hal yang umum terjadi. Untuk menonaktifkan pengikatan parameter otomatis, atur 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();
Dalam ASP.NET Core 7.0, jenis di DI diperiksa di startup 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:
BindingInfo.BindingSource
yang telah ditentukan tidak akan pernah ditimpa.BindingSource.Services
ditetapkan untuk parameter jenis kompleks yang terdaftar di kontainer DI.BindingSource.Body
ditetapkan untuk parameter jenis kompleks yang tidak terdaftar di kontainer DI.BindingSource.Path
ditetapkan untuk parameter dengan nama yang ditampilkan sebagai nilai rute di templat rute apa pun.- 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 halaman tunggal, mendapat manfaat dari penggunaan nama properti JSON untuk kesalahan validasi yang dihasilkan dari API Web. 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
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
Minimal API
Filter di aplikasi Minimal API
Filter API minimal memungkinkan pengembang untuk menerapkan logika bisnis yang mendukung:
- Menjalankan kode sebelum dan sesudah handler rute.
- Memeriksa dan memodifikasi parameter yang disediakan selama pemanggilan handler rute.
- Mencegat perilaku respons penangan rute.
Filter dapat membantu dalam skenario berikut:
- Memvalidasi parameter dan isi permintaan yang dikirim ke titik akhir.
- Mencatat informasi tentang permintaan dan respons.
- Memvalidasi bahwa permintaan menargetkan versi API yang didukung.
Untuk informasi selengkapnya, lihat Filter di aplikasi API Minimal
Mengikat array dan nilai string dari header dan string kueri
Di ASP.NET 7, mengikat string kueri ke array jenis 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 jenis kompleks didukung ketika jenis telah TryParse
diimplementasikan. Untuk informasi selengkapnya, lihat Mengikat array dan nilai string dari header dan string kueri.
Untuk informasi selengkapnya, lihat Menambahkan ringkasan atau deskripsi titik akhir.
Mengikat isi permintaan sebagai Stream
atau PipeReader
Isi permintaan dapat mengikat sebagai Stream
atau PipeReader
untuk mendukung skenario secara efisien di mana pengguna harus memproses data dan:
- Simpan data ke penyimpanan blob atau antrekan data ke penyedia antrean.
- Proses data yang disimpan dengan proses pekerja atau fungsi cloud.
Misalnya, data mungkin diantrekan ke penyimpanan Azure Queue atau disimpan di penyimpanan Azure Blob.
Untuk informasi selengkapnya, lihat Mengikat isi permintaan sebagai Stream
atau PipeReader
Overload Results.Stream Baru
Kami memperkenalkan kelebihan beban baru Results.Stream
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 gambar yang ditentukan yang dikurangi:
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 selengkapnya, lihat Contoh aliran
Hasil yang ditik untuk API minimal
Di .NET 6, IResult antarmuka diperkenalkan untuk mewakili nilai yang dikembalikan dari API minimal yang tidak menggunakan dukungan implisit untuk JSON yang menserialisasikan objek yang dikembalikan ke respons HTTP. Kelas Hasil statis digunakan untuk membuat berbagai IResult
objek yang mewakili berbagai jenis respons. Misalnya, mengatur kode status respons atau mengalihkan ke URL lain. Jenis IResult
kerangka kerja penerapan yang dikembalikan dari metode ini adalah internal, sehingga sulit untuk memverifikasi jenis tertentu IResult
yang dikembalikan dari metode dalam pengujian unit.
Di .NET 7 jenis yang IResult
diterapkan bersifat publik, memungkinkan pernyataan jenis saat pengujian. Contohnya:
[TestClass()]
public class WeatherApiTests
{
[TestMethod()]
public void MapWeatherApiTest()
{
var result = WeatherApi.GetAllWeathers();
Assert.IsInstanceOfType(result, typeof(Ok<WeatherForecast[]>));
}
}
Peningkatan uji coba unit untuk handler rute minimal
IResult jenis implementasi sekarang tersedia untuk umum di Microsoft.AspNetCore.Http.HttpResults namespace layanan. Jenis IResult
implementasi dapat digunakan untuk menguji unit penangan rute minimal saat menggunakan metode bernama alih-alih lambda.
Kode berikut menggunakan Ok<TValue>
kelas :
[Fact]
public async Task GetTodoReturnsTodoFromDatabase()
{
// Arrange
await using var context = new MockDb().CreateDbContext();
context.Todos.Add(new Todo
{
Id = 1,
Title = "Test title",
Description = "Test description",
IsDone = false
});
await context.SaveChangesAsync();
// Act
var result = await TodoEndpointsV1.GetTodo(1, context);
//Assert
Assert.IsType<Results<Ok<Todo>, NotFound>>(result);
var okResult = (Ok<Todo>)result.Result;
Assert.NotNull(okResult.Value);
Assert.Equal(1, okResult.Value.Id);
}
Untuk informasi selengkapnya, lihat IResult
jenis implementasi.
Antarmuka HttpResult baru
Antarmuka berikut di Microsoft.AspNetCore.Http namespace layanan menyediakan cara untuk mendeteksi IResult
jenis pada runtime, yang merupakan pola umum dalam implementasi filter:
- IContentTypeHttpResult
- IFileHttpResult
- INestedHttpResult
- IStatusCodeHttpResult
- IValueHttpResult
- IValueHttpResult<TValue>
Untuk informasi selengkapnya, lihat Antarmuka IHttpResult.
Peningkatan OpenAPI untuk API minimal
Microsoft.AspNetCore.OpenApi
Paket NuGet
Paket ini Microsoft.AspNetCore.OpenApi
memungkinkan interaksi dengan spesifikasi OpenAPI untuk titik akhir. Paket bertindak sebagai tautan antara model OpenAPI yang ditentukan dalam Microsoft.AspNetCore.OpenApi
paket dan titik akhir yang ditentukan dalam API Minimal. Paket ini menyediakan API yang memeriksa parameter, respons, dan metadata titik akhir untuk membuat jenis anotasi OpenAPI yang digunakan untuk menjelaskan 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
Metode WithOpenApi
ini 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;
});
Memberikan deskripsi dan ringkasan titik akhir
API minimal sekarang mendukung operasi anotasi dengan deskripsi dan ringkasan untuk pembuatan spesifikasi OpenAPI. Anda dapat memanggil metode ekstensi dan WithSummary atau menggunakan atribut [EndpointDescription] dan [EndpointSummary]).WithDescription
Untuk informasi selengkapnya, lihat OpenAPI di aplikasi API minimal
Unggahan file menggunakan IFormFile dan IFormFileCollection
API minimal sekarang mendukung pengunggahan file dengan IFormFile
dan IFormFileCollection
. Kode berikut menggunakan IFormFile dan IFormFileCollection untuk mengunggah file:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapPost("/upload", async (IFormFile file) =>
{
var tempFile = Path.GetTempFileName();
app.Logger.LogInformation(tempFile);
using var stream = File.OpenWrite(tempFile);
await file.CopyToAsync(stream);
});
app.MapPost("/upload_many", async (IFormFileCollection myFiles) =>
{
foreach (var file in myFiles)
{
var tempFile = Path.GetTempFileName();
app.Logger.LogInformation(tempFile);
using var stream = File.OpenWrite(tempFile);
await file.CopyToAsync(stream);
}
});
app.Run();
Permintaan unggahan file yang diautentikasi didukung menggunakan header Otorisasi, sertifikat klien, atau cookie header.
Tidak ada dukungan bawaan untuk antiforgery. Namun, dapat diimplementasikan menggunakan IAntiforgery
layanan .
[AsParameters]
atribut memungkinkan pengikatan parameter untuk daftar argumen
Atribut [AsParameters]
memungkinkan pengikatan parameter untuk daftar argumen. Untuk informasi selengkapnya, lihat Pengikatan parameter untuk daftar argumen dengan [AsParameters]
.
API minimal dan pengontrol API
Layanan detail masalah baru
Layanan detail masalah mengimplementasikan IProblemDetailsService antarmuka, yang mendukung pembuatan Detail Masalah untuk API HTTP.
Untuk informasi selengkapnya, lihat Layanan detail masalah.
Grup rute
Metode MapGroup ekstensi membantu mengatur grup titik akhir dengan awalan umum. Ini mengurangi kode berulang dan memungkinkan untuk menyesuaikan seluruh grup titik akhir dengan satu panggilan ke metode seperti RequireAuthorization dan WithMetadata yang menambahkan metadata titik akhir.
Misalnya, kode berikut membuat dua grup titik akhir serupa:
app.MapGroup("/public/todos")
.MapTodosApi()
.WithTags("Public");
app.MapGroup("/private/todos")
.MapTodosApi()
.WithTags("Private")
.AddEndpointFilterFactory(QueryPrivateTodos)
.RequireAuthorization();
EndpointFilterDelegate QueryPrivateTodos(EndpointFilterFactoryContext factoryContext, EndpointFilterDelegate next)
{
var dbContextIndex = -1;
foreach (var argument in factoryContext.MethodInfo.GetParameters())
{
if (argument.ParameterType == typeof(TodoDb))
{
dbContextIndex = argument.Position;
break;
}
}
// Skip filter if the method doesn't have a TodoDb parameter.
if (dbContextIndex < 0)
{
return next;
}
return async invocationContext =>
{
var dbContext = invocationContext.GetArgument<TodoDb>(dbContextIndex);
dbContext.IsPrivate = true;
try
{
return await next(invocationContext);
}
finally
{
// This should only be relevant if you're pooling or otherwise reusing the DbContext instance.
dbContext.IsPrivate = false;
}
};
}
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group)
{
group.MapGet("/", GetAllTodos);
group.MapGet("/{id}", GetTodo);
group.MapPost("/", CreateTodo);
group.MapPut("/{id}", UpdateTodo);
group.MapDelete("/{id}", DeleteTodo);
return group;
}
Dalam skenario ini, Anda dapat menggunakan alamat relatif untuk Location
header dalam hasil 201 Created
:
public static async Task<Created<Todo>> CreateTodo(Todo todo, TodoDb database)
{
await database.AddAsync(todo);
await database.SaveChangesAsync();
return TypedResults.Created($"{todo.Id}", todo);
}
Grup titik akhir pertama hanya akan cocok dengan permintaan yang diawali dan /public/todos
dapat diakses tanpa autentikasi apa pun. Grup titik akhir kedua hanya akan cocok dengan permintaan yang diawali dan /private/todos
memerlukan autentikasi.
Pabrik QueryPrivateTodos
filter titik akhir adalah fungsi lokal yang memodifikasi parameter handler TodoDb
rute untuk memungkinkan mengakses dan menyimpan data todo privat.
Grup rute juga mendukung grup berlapis dan pola awalan kompleks dengan parameter rute dan batasan. Dalam contoh berikut, dan handler rute yang dipetakan user
ke grup dapat menangkap {org}
parameter rute dan {group}
yang ditentukan dalam awalan grup luar.
Awalan juga dapat kosong. Ini dapat berguna untuk menambahkan metadata titik akhir atau filter ke sekelompok titik akhir tanpa mengubah pola rute.
var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");
Menambahkan filter atau metadata ke grup berulah dengan cara yang sama seperti menambahkannya satu per satu ke setiap titik akhir sebelum menambahkan filter atau metadata tambahan yang mungkin telah ditambahkan ke grup dalam atau titik akhir tertentu.
var outer = app.MapGroup("/outer");
var inner = outer.MapGroup("/inner");
inner.AddEndpointFilter((context, next) =>
{
app.Logger.LogInformation("/inner group filter");
return next(context);
});
outer.AddEndpointFilter((context, next) =>
{
app.Logger.LogInformation("/outer group filter");
return next(context);
});
inner.MapGet("/", () => "Hi!").AddEndpointFilter((context, next) =>
{
app.Logger.LogInformation("MapGet filter");
return next(context);
});
Dalam contoh di atas, filter luar akan mencatat permintaan masuk sebelum filter dalam meskipun ditambahkan kedua. Karena filter diterapkan ke grup yang berbeda, urutan yang ditambahkan relatif satu sama lain tidak masalah. Filter pesanan ditambahkan tidak masalah jika diterapkan ke grup yang sama atau titik akhir tertentu.
Permintaan untuk /outer/inner/
mencatat hal berikut:
/outer group filter
/inner group filter
MapGet filter
gRPC
Transcoding JSON
Transcoding JSON gRPC adalah ekstensi untuk ASP.NET Core yang membuat API JSON RESTful untuk layanan gRPC. Transcoding JSON gRPC memungkinkan:
- Aplikasi untuk memanggil layanan gRPC dengan konsep HTTP yang sudah dikenal.
- ASP.NET aplikasi gRPC Core untuk mendukung API JSON gRPC dan RESTful tanpa mereplikasi fungsionalitas.
- Dukungan eksperimental untuk menghasilkan OpenAPI dari API RESTful yang ditranskodekan dengan mengintegrasikan dengan Swashbuckle.
Untuk informasi selengkapnya, lihat transcoding GRPC JSON di aplikasi gRPC ASP.NET Core dan Gunakan OpenAPI dengan transcoding JSON gRPC ASP.NET aplikasi Core.
Pemeriksaan kesehatan gRPC di ASP.NET Core
Protokol pemeriksaan kesehatan gRPC adalah standar untuk melaporkan kesehatan aplikasi server gRPC. Aplikasi memaparkan pemeriksaan kesehatan sebagai layanan gRPC. Mereka biasanya digunakan dengan layanan pemantauan eksternal untuk memeriksa status aplikasi.
gRPC ASP.NET Core telah menambahkan dukungan bawaan untuk pemeriksaan kesehatan gRPC dengan Grpc.AspNetCore.HealthChecks
paket. Hasil dari pemeriksaan kesehatan .NET dilaporkan ke penelepon.
Untuk informasi selengkapnya, lihat pemeriksaan kesehatan gRPC di ASP.NET Core.
Dukungan kredensial panggilan yang disempurnakan
Info masuk panggilan adalah cara yang disarankan untuk mengonfigurasi klien gRPC untuk mengirim token autentikasi ke server. Klien gRPC mendukung dua fitur baru untuk membuat kredensial panggilan lebih mudah digunakan:
- Dukungan untuk kredensial panggilan dengan koneksi teks biasa. Sebelumnya, panggilan gRPC hanya mengirim info masuk panggilan jika koneksi diamankan dengan TLS. Pengaturan baru pada
GrpcChannelOptions
, yang disebutUnsafeUseInsecureChannelCallCredentials
, memungkinkan perilaku ini disesuaikan. Ada implikasi keamanan untuk tidak mengamankan koneksi dengan TLS. - Metode baru yang disebut
AddCallCredentials
tersedia dengan pabrik klien gRPC.AddCallCredentials
adalah cara cepat untuk mengonfigurasi kredensial panggilan untuk klien gRPC dan terintegrasi dengan baik dengan injeksi dependensi (DI).
Kode berikut mengonfigurasi pabrik klien gRPC untuk mengirim Authorization
metadata:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials((context, metadata) =>
{
if (!string.IsNullOrEmpty(_token))
{
metadata.Add("Authorization", $"Bearer {_token}");
}
return Task.CompletedTask;
});
Untuk informasi selengkapnya, lihat Mengonfigurasi token pembawa dengan pabrik klien gRPC.
SignalR
Hasil klien
Server sekarang mendukung permintaan hasil dari klien. Ini mengharuskan server untuk menggunakan ISingleClientProxy.InvokeAsync
dan klien untuk mengembalikan hasil dari handler-nya .On
. Hub yang sangat ditik juga dapat mengembalikan nilai dari metode antarmuka.
Untuk informasi selengkapnya, lihat Hasil klien
Injeksi dependensi untuk SignalR metode hub
SignalR metode hub sekarang mendukung layanan injeksi melalui injeksi dependensi (DI).
Konstruktor hub dapat menerima layanan dari DI sebagai parameter, yang dapat disimpan di properti di kelas untuk digunakan dalam metode hub. Untuk informasi selengkapnya, lihat Menyuntikkan layanan ke hub
Blazor
Menangani peristiwa perubahan lokasi dan status navigasi
Di .NET 7, Blazor mendukung lokasi yang mengubah peristiwa dan mempertahankan status navigasi. Ini memungkinkan Anda memperingatkan pengguna tentang pekerjaan yang belum disimpan atau melakukan tindakan terkait saat pengguna melakukan navigasi halaman.
Untuk informasi selengkapnya, lihat bagian berikut dari artikel Perutean dan navigasi :
Templat proyek kosong Blazor
Blazor memiliki dua templat proyek baru untuk memulai dari garis miring kosong. Templat proyek App Empty dan Blazor WebAssembly App Empty baru Blazor Server sama seperti rekan-rekan yang tidak kosong tetapi tanpa contoh kode. Templat kosong ini hanya menyertakan halaman dasar home , dan kami telah menghapus Bootstrap sehingga Anda dapat memulai dengan kerangka kerja CSS yang berbeda.
Untuk informasi lebih lanjut, baca artikel berikut:
Elemen kustom Blazor
Paket ini Microsoft.AspNetCore.Components.CustomElements
memungkinkan membangun elemen DOM kustom berbasis standar menggunakan Blazor.
Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.
Pengubah ikatan (@bind:after
, @bind:get
, @bind:set
)
Penting
Fitur-fitur tersebut @bind:after
//@bind:get
@bind:set
menerima pembaruan lebih lanjut saat ini. Untuk memanfaatkan pembaruan terbaru, konfirmasikan bahwa Anda telah menginstal SDK terbaru.
Menggunakan parameter panggilan balik peristiwa ([Parameter] public EventCallback<string> ValueChanged { get; set; }
) tidak didukung. Sebagai gantinya, berikan Actionmetode -returning atau Task-returning ke/@bind:set
@bind:after
.
Untuk informasi selengkapnya, lihat sumber daya berikut:
Di .NET 7, Anda dapat menjalankan logika asinkron setelah peristiwa pengikatan selesai menggunakan pengubah baru @bind:after
. Dalam contoh berikut, PerformSearch
metode asinkron berjalan secara otomatis setelah perubahan apa pun pada teks pencarian terdeteksi:
<input @bind="searchText" @bind:after="PerformSearch" />
@code {
private string searchText;
private async Task PerformSearch()
{
...
}
}
Di .NET 7, juga lebih mudah untuk menyiapkan pengikatan untuk parameter komponen. Komponen dapat mendukung pengikatan data dua arah dengan menentukan sepasang parameter:
@bind:get
: Menentukan nilai yang akan diikat.@bind:set
: Menentukan panggilan balik saat nilai berubah.
Pengubah @bind:get
dan @bind:set
selalu digunakan bersama-sama.
Contoh:
@* Elements *@
<input type="text" @bind="text" @bind:after="() => { }" />
<input type="text" @bind:get="text" @bind:set="(value) => { }" />
<input type="text" @bind="text" @bind:after="AfterAsync" />
<input type="text" @bind:get="text" @bind:set="SetAsync" />
<input type="text" @bind="text" @bind:after="() => { }" />
<input type="text" @bind:get="text" @bind:set="(value) => { }" />
<input type="text" @bind="text" @bind:after="AfterAsync" />
<input type="text" @bind:get="text" @bind:set="SetAsync" />
@* Components *@
<InputText @bind-Value="text" @bind-Value:after="() => { }" />
<InputText @bind-Value:get="text" @bind-Value:set="(value) => { }" />
<InputText @bind-Value="text" @bind-Value:after="AfterAsync" />
<InputText @bind-Value:get="text" @bind-Value:set="SetAsync" />
<InputText @bind-Value="text" @bind-Value:after="() => { }" />
<InputText @bind-Value:get="text" @bind-Value:set="(value) => { }" />
<InputText @bind-Value="text" @bind-Value:after="AfterAsync" />
<InputText @bind-Value:get="text" @bind-Value:set="SetAsync" />
@code {
private string text = "";
private void After(){}
private void Set() {}
private Task AfterAsync() { return Task.CompletedTask; }
private Task SetAsync(string value) { return Task.CompletedTask; }
}
Untuk informasi selengkapnya tentang InputText
komponen, lihat komponen input ASP.NET CoreBlazor.
Peningkatan Hot Reload
Di .NET 7, dukungan Hot Reload mencakup hal berikut:
- Komponen mengatur ulang parameternya ke nilai defaultnya saat nilai dihapus.
- Blazor WebAssembly:
- Tambahkan jenis baru.
- Tambahkan kelas berlapis.
- Tambahkan metode statis dan instans ke jenis yang ada.
- Tambahkan bidang statis dan metode ke jenis yang sudah ada.
- Tambahkan lambda statis ke metode yang ada.
- Tambahkan lambda yang menangkap
this
ke metode yang sudah ada yang sudah diambilthis
sebelumnya.
Permintaan autentikasi dinamis dengan MSAL di Blazor WebAssembly
Baru di .NET 7, Blazor WebAssembly mendukung pembuatan permintaan autentikasi dinamis saat runtime dengan parameter kustom untuk menangani skenario autentikasi tingkat lanjut.
Untuk informasi lebih lanjut, baca artikel berikut:
Blazor WebAssembly penyempurnaan penelusuran kesalahan
Blazor WebAssembly penelusuran kesalahan memiliki penyempurnaan berikut:
- Dukungan untuk pengaturan Just My Code untuk menampilkan atau menyembunyikan anggota jenis yang bukan dari kode pengguna.
- Dukungan untuk memeriksa array multidirmani.
- Call Stack sekarang menunjukkan nama yang benar untuk metode asinkron.
- Evaluasi ekspresi yang ditingkatkan.
- Penanganan kata kunci yang
new
benar pada anggota turunan. - Dukungan untuk atribut terkait debugger di
System.Diagnostics
.
System.Security.Cryptography
dukungan di WebAssembly
.NET 6 mendukung keluarga SHA dari algoritma hashing saat berjalan di WebAssembly. .NET 7 memungkinkan lebih banyak algoritma kriptografi dengan memanfaatkan SubtleCrypto, jika memungkinkan, dan kembali ke implementasi .NET ketika SubtleCrypto tidak dapat digunakan. Algoritma berikut didukung di WebAssembly di .NET 7:
- SHA1
- SHA256
- SHA384
- SHA512
- HMACSHA1
- HMACSHA256
- HMACSHA384
- HMACSHA512
- AES-CBC
- PBKDF2
- HKDF
Untuk informasi selengkapnya, lihat Pengembang yang menargetkan browser-wasm dapat menggunakan API Web Crypto (dotnet/runtime #40074).
Menyuntikkan layanan ke dalam atribut validasi kustom
Anda sekarang dapat menyuntikkan layanan ke dalam atribut validasi kustom. Blazor menyiapkan ValidationContext
sehingga dapat digunakan sebagai penyedia layanan.
Untuk informasi selengkapnya, lihat validasi formulir ASP.NET CoreBlazor.
Input*
komponen di luar EditContext
/EditForm
Komponen input bawaan sekarang didukung di luar formulir dalam Razor markup komponen.
Untuk informasi selengkapnya, lihat komponen input ASP.NET CoreBlazor.
Perubahan templat proyek
Ketika .NET 6 dirilis tahun lalu, markup _Host
HTML halaman (Pages/_Host.chstml
) dibagi antara _Host
halaman dan halaman baru _Layout
(Pages/_Layout.chstml
) dalam templat proyek .NET 6 Blazor Server .
Di .NET 7, markup HTML telah dikombinasikan ulang dengan _Host
halaman dalam templat proyek.
Beberapa perubahan tambahan dilakukan pada Blazor templat proyek. Tidak layak untuk mencantumkan setiap perubahan pada templat dalam dokumentasi. Untuk memigrasikan aplikasi ke .NET 7 untuk mengadopsi semua perubahan, lihat Migrasi dari ASP.NET Core 6.0 ke 7.0.
Komponen eksperimental QuickGrid
Komponen baru QuickGrid
menyediakan komponen kisi data yang nyaman untuk persyaratan paling umum dan sebagai arsitektur referensi dan garis besar performa bagi siapa pun yang membangun Blazor komponen kisi data.
Untuk informasi selengkapnya, lihat komponen ASP.NET Core Blazor QuickGrid.
Demo langsung: QuickGrid untuk Blazor aplikasi sampel
Peningkatan virtualisasi
Peningkatan virtualisasi di .NET 7:
- Komponen ini
Virtualize
mendukung penggunaan dokumen itu sendiri sebagai akar gulir, sebagai alternatif untuk memiliki beberapa elemen lain denganoverflow-y: scroll
diterapkan. Virtualize
Jika komponen ditempatkan di dalam elemen yang memerlukan nama tag anak tertentu,SpacerElement
memungkinkan Anda untuk mendapatkan atau mengatur nama tag spacer virtualisasi.
Untuk informasi selengkapnya, lihat bagian berikut dari artikel Virtualisasi :
MouseEventArgs
Memperbarui
MovementX
dan MovementY
telah ditambahkan ke MouseEventArgs
.
Untuk informasi selengkapnya, lihat penanganan peristiwa ASP.NET CoreBlazor.
Halaman pemuatan baru Blazor
Blazor WebAssembly Templat proyek memiliki UI pemuatan baru yang menunjukkan kemajuan pemuatan aplikasi.
Untuk informasi selengkapnya, lihat startup ASP.NET CoreBlazor.
Diagnostik yang ditingkatkan untuk autentikasi di Blazor WebAssembly
Untuk membantu mendiagnosis masalah autentikasi di Blazor WebAssembly aplikasi, pembuatan log terperinci tersedia.
Untuk informasi selengkapnya, lihat pengelogan ASP.NET CoreBlazor.
Interop JavaScript di WebAssembly
JavaScript [JSImport]
/[JSExport]
interop API adalah mekanisme tingkat rendah baru untuk menggunakan .NET di Blazor WebAssembly dan aplikasi berbasis JavaScript. Dengan kemampuan interop JavaScript baru ini, Anda dapat memanggil kode .NET dari JavaScript menggunakan runtime .NET WebAssembly dan memanggil fungsionalitas JavaScript dari .NET tanpa dependensi pada Blazor model komponen UI.
Untuk informasi selengkapnya:
- Interop JavaScript JSImport/JSExport dengan ASP.NET Core Blazor: Berkaitan hanya dengan Blazor WebAssembly aplikasi.
- Interop JavaScript '[JSImport]'/'[JSExport]' di .NET WebAssembly: Hanya berkaitan dengan aplikasi JavaScript yang tidak bergantung pada Blazor model komponen UI.
Pendaftaran berskala penyedia status autentikasi
Sebelum rilis .NET 7, AuthenticationStateProvider
terdaftar dalam kontainer layanan dengan AddScoped
. Ini membuatnya sulit untuk men-debug aplikasi, karena memaksa urutan pendaftaran layanan tertentu saat memberikan implementasi kustom. Karena perubahan kerangka kerja internal dari waktu ke waktu, tidak perlu lagi mendaftar AuthenticationStateProvider
dengan AddScoped
.
Dalam kode pengembang, buat perubahan berikut pada pendaftaran layanan penyedia status autentikasi:
- builder.Services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
+ builder.Services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
Dalam contoh sebelumnya, ExternalAuthStateProvider
adalah implementasi layanan pengembang.
Penyempurnaan pada alat build .NET WebAssembly
Fitur baru dalam wasm-tools
beban kerja untuk .NET 7 yang membantu meningkatkan performa dan menangani pengecualian:
- Dukungan WebAssembly Single Instruction, Multiple Data (SIMD) (hanya dengan AOT, tidak didukung oleh Apple Safari)
- Dukungan penanganan pengecualian WebAssembly
Untuk informasi selengkapnya, lihat ASP.NET alat build Core Blazor WebAssembly dan kompilasi ahead-of-time (AOT).
Blazor Hybrid
URL Eksternal
Opsi telah ditambahkan yang mengizinkan pembukaan halaman web eksternal di browser.
Untuk informasi selengkapnya, lihat perutean dan navigasi ASP.NET CoreBlazor Hybrid.
Keamanan
Panduan baru tersedia untuk Blazor Hybrid skenario keamanan. Untuk informasi lebih lanjut, baca artikel berikut:
- ASP.NET Core Blazor Hybrid autentikasi dan otorisasi
- Pertimbangan keamanan ASP.NET Core Blazor Hybrid
Performa
Middleware penembolokan output
Penembolokan output adalah middleware baru yang menyimpan respons dari aplikasi web dan melayaninya dari cache daripada menghitungnya setiap saat. Penembolokan output berbeda dari penembolokan respons dengan cara berikut:
- Perilaku penembolokan dapat dikonfigurasi di server.
- Entri singgahan dapat dibatalkan secara terprogram.
- Penguncian sumber daya mengurangi risiko stampede cache dan kawanan guntur.
- Validasi ulang cache berarti server dapat mengembalikan
304 Not Modified
kode status HTTP alih-alih isi respons yang di-cache. - Media penyimpanan cache dapat diperluas.
Untuk informasi selengkapnya, lihat Gambaran umum penembolokan dan Middleware penembolokan output.
Peningkatan HTTP/3
Rilis ini:
- Membuat HTTP/3 didukung sepenuhnya oleh ASP.NET Core, http tidak lagi eksperimental.
- KestrelMeningkatkan dukungan untuk HTTP/3. Dua bidang utama peningkatan adalah paritas fitur dengan HTTP/1.1 dan HTTP/2, dan performa.
- Menyediakan dukungan penuh untuk UseHttps(ListenOptions, X509Certificate2) dengan HTTP/3. Kestrel menawarkan opsi lanjutan untuk mengonfigurasi sertifikat koneksi, seperti menghubungkan ke Indikasi Nama Server (SNI).
- Menambahkan dukungan untuk HTTP/3 di HTTP.sys dan IIS.
Contoh berikut menunjukkan cara menggunakan panggilan balik SNI untuk mengatasi opsi TLS:
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(8080, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
var options = new SslServerAuthenticationOptions
{
ServerCertificate =
MyResolveCertForHost(context.ClientHelloInfo.ServerName)
};
return new ValueTask<SslServerAuthenticationOptions>(options);
},
});
});
});
Pekerjaan signifikan dilakukan di .NET 7 untuk mengurangi alokasi HTTP/3. Anda dapat melihat beberapa peningkatan tersebut dalam GitHub PR berikut:
- HTTP/3: Hindari alokasi token pembatalan per permintaan
- HTTP/3: Hindari alokasi ConnectionAbortedException
- HTTP/3: Pengumpulan ValueTask
Peningkatan performa HTTP/2
.NET 7 memperkenalkan arsitektur ulang yang signifikan tentang cara Kestrel memproses permintaan HTTP/2. ASP.NET aplikasi Core dengan koneksi HTTP/2 yang sibuk akan mengalami pengurangan penggunaan CPU dan throughput yang lebih tinggi.
Sebelumnya, implementasi multipleks HTTP/2 bergantung pada pengendalian kunci yang permintaannya dapat menulis ke koneksi TCP yang mendasar. Antrean aman utas menggantikan kunci tulis. Sekarang, daripada memperebutkan utas mana yang akan menggunakan kunci tulis, permintaan sekarang mengantre dan konsumen khusus memprosesnya. Sumber daya CPU yang sebelumnya terbuang tersedia untuk rest aplikasi.
Salah satu tempat di mana peningkatan ini dapat diperhatikan adalah di gRPC, kerangka kerja RPC populer yang menggunakan HTTP/2. Kestrel + tolok ukur gRPC menunjukkan peningkatan dramatis:
Perubahan dilakukan dalam kode penulisan bingkai HTTP/2 yang meningkatkan performa ketika ada beberapa aliran yang mencoba menulis data pada satu koneksi HTTP/2. Kami sekarang mengirimkan pekerjaan TLS ke kumpulan utas dan lebih cepat melepaskan kunci tulis yang dapat diperoleh aliran lain untuk menulis data mereka. Pengurangan waktu tunggu dapat menghasilkan peningkatan performa yang signifikan dalam kasus di mana ada ketidakcocokan untuk kunci tulis ini. Tolok ukur gRPC dengan 70 aliran pada satu koneksi (dengan TLS) menunjukkan peningkatan ~ 15% dalam permintaan per detik (RPS) dengan perubahan ini.
Dukungan Http/2 WebSockets
.NET 7 memperkenalkan WebSocket melalui dukungan HTTP/2 untuk Kestrel, SignalR klien JavaScript, dan SignalR dengan Blazor WebAssembly.
Menggunakan WebSocket melalui HTTP/2 memanfaatkan fitur baru seperti:
- Pemadatan header.
- Multiplexing, yang mengurangi waktu dan sumber daya yang diperlukan saat membuat beberapa permintaan ke server.
Fitur yang didukung ini tersedia di Kestrel semua platform yang diaktifkan HTTP/2. Negosiasi versi otomatis di browser dan Kestrel, sehingga tidak ada API baru yang diperlukan.
Untuk informasi selengkapnya, lihat Dukungan Http/2 WebSockets.
Kestrel peningkatan performa pada mesin inti tinggi
KestrelConcurrentQueue<T> digunakan untuk banyak tujuan. Salah satu tujuannya adalah menjadwalkan operasi I/O dalam Kestreltransportasi Soket default. Pemartisian ConcurrentQueue
berdasarkan soket terkait mengurangi ketidakcocokan dan meningkatkan throughput pada mesin dengan banyak inti CPU.
Pembuatan profil pada mesin inti tinggi pada .NET 6 menunjukkan ketidakcocokan yang signifikan dalam salah Kestrelsatu instans lain ConcurrentQueue
, PinnedMemoryPool
yang Kestrel menggunakan untuk buffer byte cache.
Dalam .NET 7, Kestrelkumpulan memori dipartisi dengan cara yang sama seperti antrean I/O-nya, yang menyebabkan ketidakcocokan 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 tolok ukur HTTPS JSON kami.
ServerReady
peristiwa untuk mengukur waktu startup
Aplikasi yang menggunakan EventSource dapat mengukur waktu startup untuk memahami dan mengoptimalkan performa startup. Peristiwa baru ServerReady
di Microsoft.AspNetCore.Hosting mewakili titik di mana server siap merespons permintaan.
Server
Peristiwa ServerReady baru untuk mengukur waktu mulai
Peristiwa ServerReady
telah ditambahkan untuk mengukur waktu mulai 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 selengkapnya, lihat Menyalin bayangan di IIS.
Lain-lain
Kestrel peningkatan rantai sertifikat lengkap
HttpsConnectionAdapterOptions memiliki properti ServerCertificateChain baru jenis X509Certificate2Collection, yang memudahkan untuk memvalidasi rantai sertifikat dengan memungkinkan rantai penuh termasuk sertifikat perantara ditentukan. Lihat dotnet/aspnetcore#21513 untuk detail selengkapnya.
dotnet watch
Output konsol yang ditingkatkan untuk dotnet watch
Output konsol dari dotnet watch telah ditingkatkan agar lebih selaras😍 dengan pengelogan ASP.NET Core dan untuk menonjol dengan 😮emoji.
Berikut adalah contoh tampilan output baru:
Untuk informasi selengkapnya, lihat permintaan pull GitHub ini.
Mengonfigurasi dotnet watch untuk selalu menghidupkan ulang untuk pengeditan kasar
Pengeditan kasar adalah pengeditan yang tidak dapat dimuat ulang dengan panas. Untuk mengonfigurasi dotnet watch agar selalu dimulai ulang tanpa permintaan untuk pengeditan yang kasar, atur DOTNET_WATCH_RESTART_ON_RUDE_EDIT
variabel lingkungan ke true
.
Mode gelap halaman pengecualian pengembang
Dukungan mode gelap telah ditambahkan ke halaman pengecualian pengembang, berkat kontribusi oleh Patrick Westerhoff. Untuk menguji mode gelap di browser, dari halaman alat pengembang, atur mode ke gelap. Misalnya, di Firefox:
Di Chrome:
Opsi templat proyek untuk menggunakan metode Program.Main alih-alih pernyataan tingkat atas
Templat .NET 7 menyertakan opsi untuk tidak menggunakan pernyataan tingkat atas dan menghasilkan namespace
dan metode yang Main
dideklarasikan pada Program
kelas.
Menggunakan .NET CLI, gunakan --use-program-main
opsi :
dotnet new web --use-program-main
Dengan Visual Studio, pilih kotak centang Jangan gunakan pernyataan tingkat atas baru selama pembuatan proyek:
Templat Angular dan React yang Diperbarui
Templat proyek Angular telah diperbarui ke Angular 14. Templat proyek React telah diperbarui ke React 18.2.
Mengelola JSON Web Token dalam pengembangan dengan dotnet user-jwts
Alat baris perintah baru dotnet user-jwts
dapat membuat dan mengelola JSON Web Token (JWT) lokal khusus aplikasi. Untuk informasi selengkapnya, lihat Mengelola JSON Web Token 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 memanggil AdditionalRequestHeaders()
di W3CLoggerOptions:
services.AddW3CLogging(logging =>
{
logging.AdditionalRequestHeaders.Add("x-forwarded-for");
logging.AdditionalRequestHeaders.Add("x-client-ssl-protocol");
});
Untuk informasi selengkapnya, lihat Opsi W3CLogger.
Meminta dekompresi
Middleware dekompresi Permintaan baru:
- Memungkinkan titik akhir API untuk menerima permintaan dengan konten terkompresi.
Content-Encoding
Menggunakan header HTTP untuk mengidentifikasi dan mendekompresi permintaan secara otomatis yang berisi konten terkompresi.- Menghilangkan kebutuhan untuk menulis kode untuk menangani permintaan terkompresi.
Untuk informasi selengkapnya, lihat Meminta middleware dekompresi.
ASP.NET Core