tata letak ASP.NET Core Blazor
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Artikel ini menjelaskan cara membuat komponen tata letak yang dapat digunakan kembali untuk Blazor aplikasi.
Kegunaan Blazor tata letak
Beberapa elemen aplikasi, seperti menu, pesan hak cipta, dan logo perusahaan, biasanya merupakan bagian dari presentasi aplikasi secara keseluruhan. Menempatkan salinan markup untuk elemen-elemen ini ke semua komponen aplikasi tidak efisien. Setiap kali salah satu elemen ini diperbarui, setiap komponen yang menggunakan elemen harus diperbarui. Pendekatan ini mahal untuk dipertahankan dan dapat menyebabkan konten yang tidak konsisten jika pembaruan terlewatkan. Tata letak menyelesaikan masalah ini.
Tata Blazor letak adalah Razor komponen yang berbagi markup dengan komponen yang mereferensikannya. Tata letak dapat menggunakan pengikatan data, injeksi dependensi, dan fitur komponen lainnya.
Komponen tata letak
Membuat komponen tata letak
Untuk membuat komponen tata letak:
- Buat komponen yang Razor ditentukan oleh Razor templat atau kode C#. Komponen tata letak berdasarkan Razor templat menggunakan
.razor
ekstensi file seperti komponen biasa Razor . Karena komponen tata letak dibagikan di seluruh komponen aplikasi, komponen tersebut biasanya ditempatkan di folder atauLayout
aplikasiShared
. Namun, tata letak dapat ditempatkan di lokasi mana pun yang dapat diakses oleh komponen yang menggunakannya. Misalnya, tata letak dapat ditempatkan di folder yang sama dengan komponen yang menggunakannya. - Warisi komponen dari LayoutComponentBase. LayoutComponentBase menentukan Body properti (RenderFragment jenis) untuk konten yang dirender di dalam tata letak.
- Razor Gunakan sintaks
@Body
untuk menentukan lokasi dalam markup tata letak tempat konten dirender.
Catatan
Untuk informasi selengkapnya tentang RenderFragment, lihat komponen ASP.NET CoreRazor.
Komponen berikut menunjukkan DoctorWhoLayout
Razor templat komponen tata letak. Tata letak mewarisi LayoutComponentBase dan mengatur @Body
antara bilah navigasi (<nav>...</nav>
) dan footer (<footer>...</footer>
).
DoctorWhoLayout.razor
:
@inherits LayoutComponentBase
<PageTitle>Doctor Who® Database</PageTitle>
<header>
<h1>Doctor Who® Database</h1>
</header>
<nav>
<a href="main-list">Main Episode List</a>
<a href="search">Search</a>
<a href="new">Add Episode</a>
</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/ https://www.bbc.com";
}
@inherits LayoutComponentBase
<PageTitle>Doctor Who® Database</PageTitle>
<header>
<h1>Doctor Who® Database</h1>
</header>
<nav>
<a href="main-list">Main Episode List</a>
<a href="search">Search</a>
<a href="new">Add Episode</a>
</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/ https://www.bbc.com";
}
@inherits LayoutComponentBase
<header>
<h1>Doctor Who™ Episode Database</h1>
</header>
<nav>
<a href="main-list">Main Episode List</a>
<a href="search">Search</a>
<a href="new">Add Episode</a>
</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
@inherits LayoutComponentBase
<header>
<h1>Doctor Who™ Episode Database</h1>
</header>
<nav>
<a href="main-list">Main Episode List</a>
<a href="search">Search</a>
<a href="new">Add Episode</a>
</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
@inherits LayoutComponentBase
<header>
<h1>Doctor Who™ Episode Database</h1>
</header>
<nav>
<a href="main-list">Main Episode List</a>
<a href="search">Search</a>
<a href="new">Add Episode</a>
</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
@inherits LayoutComponentBase
<header>
<h1>Doctor Who™ Episode Database</h1>
</header>
<nav>
<a href="main-list">Main Episode List</a>
<a href="search">Search</a>
<a href="new">Add Episode</a>
</nav>
@Body
<footer>
@TrademarkMessage
</footer>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
MainLayout
komponen
Dalam aplikasi yang dibuat dari templat proyek, MainLayout
komponen adalah tata letak default aplikasi.Blazor BlazorTata letak mengadopsi Flexbox layout model (MDN documentation) (spesifikasi W3C).
BlazorFitur isolasi CSS menerapkan gaya CSS terisolasi ke MainLayout
komponen. Menurut konvensi, gaya disediakan oleh lembar gaya yang menyertainya dengan nama yang sama, MainLayout.razor.css
. Implementasi kerangka kerja ASP.NET Core dari lembar gaya tersedia untuk diperiksa di sumber referensi ASP.NET Core (dotnet/aspnetcore
repositori GitHub):
Catatan
Tautan dokumentasi ke sumber referensi .NET biasanya memuat cabang default repositori, yang mewakili pengembangan saat ini untuk rilis .NET berikutnya. Untuk memilih tag rilis tertentu, gunakan daftar dropdown Beralih cabang atau tag. Untuk informasi lebih lanjut, lihat Cara memilih tag versi kode sumber ASP.NET Core (dotnet/AspNetCore.Docs #26205).
BlazorFitur isolasi CSS menerapkan gaya CSS terisolasi ke MainLayout
komponen. Menurut konvensi, gaya disediakan oleh lembar gaya yang menyertainya dengan nama yang sama, MainLayout.razor.css
.
Menerapkan tata letak
Membuat namespace tata letak tersedia
Lokasi file tata letak dan namespace berubah dari waktu ke Blazor waktu untuk kerangka kerja. Bergantung pada versi Blazor dan jenis Blazor aplikasi yang Anda buat, Anda mungkin perlu menunjukkan namespace tata letak saat menggunakannya. Saat mereferensikan implementasi tata letak dan tata letak tidak ditemukan tanpa menunjukkan namespace tata letak, lakukan salah satu pendekatan berikut:
Tambahkan direktif
@using
ke_Imports.razor
file untuk lokasi tata letak. Dalam contoh berikut, folder tata letak dengan namaLayout
berada di dalamComponents
folder, dan namespace aplikasi adalahBlazorSample
:@using BlazorSample.Components.Layout
Tambahkan direktif
@using
di bagian atas definisi komponen tempat tata letak digunakan:@using BlazorSample.Components.Layout @layout DoctorWhoLayout
Sepenuhnya memenuhi syarat namespace tata letak tempat tata letak digunakan:
@layout BlazorSample.Components.Layout.DoctorWhoLayout
Menerapkan tata letak ke komponen
Gunakan direktif @layout
Razor untuk menerapkan tata letak ke komponen yang dapat dirutekan Razor yang memiliki arahan @page
. Pengkompilasi dikonversi @layout
menjadi LayoutAttribute dan menerapkan atribut ke kelas komponen.
Konten komponen berikut Episodes
dimasukkan ke DoctorWhoLayout
dalam pada posisi @Body
.
Episodes.razor
:
@page "/episodes"
@layout DoctorWhoLayout
<h2>Doctor Who® Episodes</h2>
<ul>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfknq">
<em>The Ribos Operation</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfdsb">
<em>The Sunmakers</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vhc26">
<em>Nightmare of Eden</em>
</a>
</li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout
<h2>Doctor Who® Episodes</h2>
<ul>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfknq">
<em>The Ribos Operation</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfdsb">
<em>The Sunmakers</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vhc26">
<em>Nightmare of Eden</em>
</a>
</li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout
<h2>Episodes</h2>
<ul>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfknq">
<em>The Ribos Operation</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfdsb">
<em>The Sun Makers</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vhc26">
<em>Nightmare of Eden</em>
</a>
</li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout
<h2>Episodes</h2>
<ul>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfknq">
<em>The Ribos Operation</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfdsb">
<em>The Sun Makers</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vhc26">
<em>Nightmare of Eden</em>
</a>
</li>
</ul>
@page "/episodes"
@layout DoctorWhoLayout
<h2>Episodes</h2>
<ul>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfknq">
<em>The Ribos Operation</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vfdsb">
<em>The Sun Makers</em>
</a>
</li>
<li>
<a href="https://www.bbc.co.uk/programmes/p00vhc26">
<em>Nightmare of Eden</em>
</a>
</li>
</ul>
Markup HTML yang dirender berikut diproduksi oleh sebelumnya DoctorWhoLayout
dan Episodes
komponen. Markup asing tidak muncul untuk fokus pada konten yang disediakan oleh dua komponen yang terlibat:
- Judul "database" H1 (
<h1>...</h1>
) di header (<header>...</header>
), bilah navigasi (<nav>...</nav>
), dan informasi merek dagang di footer (<footer>...</footer>
) berasal dariDoctorWhoLayout
komponen. - Judul "episode" H2 (
<h2>...</h2>
) dan daftar episode (<ul>...</ul>
) berasal dariEpisodes
komponen.
<header>
<h1 ...>...</h1>
</header>
<nav>
...
</nav>
<h2>...</h2>
<ul>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
<footer>
...
</footer>
Menentukan tata letak secara langsung dalam komponen akan mengambil alih tata letak default:
- Diatur oleh direktif yang
@layout
diimpor dari file, seperti yang_Imports.razor
dijelaskan dalam bagian Terapkan tata letak berikut ini ke folder komponen . - Atur sebagai tata letak default aplikasi, seperti yang dijelaskan di bagian Terapkan tata letak default ke aplikasi nanti di artikel ini.
Menerapkan tata letak ke folder komponen
Setiap folder aplikasi dapat secara opsional berisi file templat bernama _Imports.razor
. Pengkompilasi mencakup arahan yang ditentukan dalam file impor di semua Razor templat dalam folder yang sama dan secara rekursif di semua subfoldernya. Oleh karena itu, file yang _Imports.razor
berisi @layout DoctorWhoLayout
memastikan bahwa semua komponen dalam folder menggunakan DoctorWhoLayout
komponen . Tidak perlu berulang kali menambahkan @layout DoctorWhoLayout
ke semua Razor komponen (.razor
) dalam folder dan subfolder.
_Imports.razor
:
@layout DoctorWhoLayout
...
File _Imports.razor
ini mirip dengan file _ViewImports.cshtml untuk Razor tampilan dan halaman tetapi diterapkan khusus untuk Razor file komponen.
Menentukan tata letak dalam _Imports.razor
mengambil alih tata letak yang ditentukan sebagai tata letak aplikasi default router, yang dijelaskan di bagian berikut.
Peringatan
Jangan tambahkan Razor@layout
direktif ke file akar_Imports.razor
, yang menghasilkan perulangan tata letak tak terbatas. Untuk mengontrol tata letak aplikasi default, tentukan tata letak dalam Router komponen. Untuk informasi selengkapnya, lihat bagian Menerapkan tata letak default ke aplikasi berikut ini.
Catatan
Direktif @layout
Razor hanya menerapkan tata letak untuk komponen yang dapat dirutekan Razor dengan direktif @page
.
Menerapkan tata letak default ke aplikasi
Tentukan tata letak aplikasi default di Router komponen komponen RouteView . DefaultLayout Gunakan parameter untuk mengatur jenis tata letak:
<RouteView RouteData="routeData" DefaultLayout="typeof({LAYOUT})" />
Dalam contoh sebelumnya, {LAYOUT}
tempat penampung adalah tata letak (misalnya, DoctorWhoLayout
jika nama file tata letak adalah DoctorWhoLayout.razor
). Anda mungkin perlu mengidenfitas namespace tata letak tergantung pada versi .NET dan jenis Blazor aplikasi. Untuk informasi selengkapnya, lihat bagian Membuat namespace tata letak tersedia .
Menentukan tata letak sebagai tata letak default dalam Router komponen RouteView adalah praktik yang berguna karena Anda dapat mengambil alih tata letak berdasarkan per komponen atau per folder, seperti yang dijelaskan di bagian sebelumnya dari artikel ini. Sebaiknya gunakan Router komponen untuk mengatur tata letak default aplikasi karena ini adalah pendekatan yang paling umum dan fleksibel untuk menggunakan tata letak.
Menerapkan tata letak ke konten arbitrer (LayoutView
komponen)
Untuk mengatur tata letak untuk konten templat arbitrer Razor , tentukan tata letak dengan LayoutView komponen. Anda dapat menggunakan LayoutView dalam komponen apa pun Razor . Contoh berikut mengatur komponen tata letak bernama ErrorLayout
untuk MainLayout
templat komponen NotFound (<NotFound>...</NotFound>
).
<Router ...>
<Found ...>
...
</Found>
<NotFound>
<LayoutView Layout="typeof(ErrorLayout)">
<h1>Page not found</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
Anda mungkin perlu namespace identity tata letak tergantung pada versi .NET dan jenis Blazor aplikasi. Untuk informasi selengkapnya, lihat bagian Membuat namespace tata letak tersedia .
Penting
Blazor Web Apps tidak menggunakan NotFound parameter (<NotFound>...</NotFound>
markup), tetapi parameter didukung untuk kompatibilitas mundur untuk menghindari perubahan yang melanggar dalam kerangka kerja. Sisi server ASP.NET alur middleware Core memproses permintaan di server. Gunakan teknik sisi server untuk menangani permintaan buruk. Untuk informasi selengkapnya, lihat mode render ASP.NET CoreBlazor.
Catatan
Dengan rilis ASP.NET Core 5.0.1 dan untuk rilis 5.x tambahan, komponen Router
menyertakan parameter PreferExactMatches
yang diatur ke @true
. Untuk informasi lebih lanjut, lihat Migrasi dari ASP.NET Core 3.1 ke 5.0.
Tata letak berlapis
Komponen dapat mereferensikan tata letak yang pada gilirannya mereferensikan tata letak lain. Misalnya, tata letak berlapis digunakan untuk membuat struktur menu multi-tingkat.
Contoh berikut menunjukkan cara menggunakan tata letak berlapis. Komponen Episodes
yang diperlihatkan di bagian Terapkan tata letak ke komponen adalah komponen yang akan ditampilkan. Komponen mereferensikan DoctorWhoLayout
komponen.
Komponen berikut DoctorWhoLayout
adalah versi contoh yang dimodifikasi yang ditunjukkan sebelumnya dalam artikel ini. Elemen header dan footer dihapus, dan tata letak mereferensikan tata letak lain, ProductionsLayout
. Komponen Episodes
dirender di mana @Body
muncul di DoctorWhoLayout
.
DoctorWhoLayout.razor
:
@inherits LayoutComponentBase
@layout ProductionsLayout
<PageTitle>Doctor Who® Database</PageTitle>
<h1>Doctor Who® Database</h1>
<nav>
<a href="main-episode-list">Main Episode List</a>
<a href="episode-search">Search</a>
<a href="new-episode">Add Episode</a>
</nav>
@Body
<div>
@TrademarkMessage
</div>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/ https://www.bbc.com";
}
@inherits LayoutComponentBase
@layout ProductionsLayout
<PageTitle>Doctor Who® Database</PageTitle>
<h1>Doctor Who® Database</h1>
<nav>
<a href="main-episode-list">Main Episode List</a>
<a href="episode-search">Search</a>
<a href="new-episode">Add Episode</a>
</nav>
@Body
<div>
@TrademarkMessage
</div>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/ https://www.bbc.com";
}
@inherits LayoutComponentBase
@layout ProductionsLayout
<h1>Doctor Who™ Episode Database</h1>
<nav>
<a href="main-episode-list">Main Episode List</a>
<a href="episode-search">Search</a>
<a href="new-episode">Add Episode</a>
</nav>
@Body
<div>
@TrademarkMessage
</div>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
@inherits LayoutComponentBase
@layout ProductionsLayout
<h1>Doctor Who™ Episode Database</h1>
<nav>
<a href="main-episode-list">Main Episode List</a>
<a href="episode-search">Search</a>
<a href="new-episode">Add Episode</a>
</nav>
@Body
<div>
@TrademarkMessage
</div>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
@inherits LayoutComponentBase
@layout ProductionsLayout
<h1>Doctor Who™ Episode Database</h1>
<nav>
<a href="main-episode-list">Main Episode List</a>
<a href="episode-search">Search</a>
<a href="new-episode">Add Episode</a>
</nav>
@Body
<div>
@TrademarkMessage
</div>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
@inherits LayoutComponentBase
@layout ProductionsLayout
<h1>Doctor Who™ Episode Database</h1>
<nav>
<a href="main-episode-list">Main Episode List</a>
<a href="episode-search">Search</a>
<a href="new-episode">Add Episode</a>
</nav>
@Body
<div>
@TrademarkMessage
</div>
@code {
public string TrademarkMessage { get; set; } =
"Doctor Who is a registered trademark of the BBC. " +
"https://www.doctorwho.tv/";
}
Komponen ProductionsLayout
berisi elemen tata letak tingkat atas, di mana elemen header (<header>...</header>
) dan footer (<footer>...</footer>
) sekarang berada. dengan DoctorWhoLayout
Episodes
komponen dirender di mana @Body
muncul.
ProductionsLayout.razor
:
@inherits LayoutComponentBase
<header>
<h1>Productions</h1>
</header>
<nav>
<a href="main-production-list">Main Production List</a>
<a href="production-search">Search</a>
<a href="new-production">Add Production</a>
</nav>
@Body
<footer>
Footer of Productions Layout
</footer>
@inherits LayoutComponentBase
<header>
<h1>Productions</h1>
</header>
<nav>
<a href="main-production-list">Main Production List</a>
<a href="production-search">Search</a>
<a href="new-production">Add Production</a>
</nav>
@Body
<footer>
Footer of Productions Layout
</footer>
@inherits LayoutComponentBase
<header>
<h1>Productions</h1>
</header>
<nav>
<a href="main-production-list">Main Production List</a>
<a href="production-search">Search</a>
<a href="new-production">Add Production</a>
</nav>
@Body
<footer>
Footer of Productions Layout
</footer>
@inherits LayoutComponentBase
<header>
<h1>Productions</h1>
</header>
<nav>
<a href="main-production-list">Main Production List</a>
<a href="production-search">Search</a>
<a href="new-production">Add Production</a>
</nav>
@Body
<footer>
Footer of Productions Layout
</footer>
@inherits LayoutComponentBase
<header>
<h1>Productions</h1>
</header>
<nav>
<a href="main-production-list">Main Production List</a>
<a href="production-search">Search</a>
<a href="new-production">Add Production</a>
</nav>
@Body
<footer>
Footer of Productions Layout
</footer>
@inherits LayoutComponentBase
<header>
<h1>Productions</h1>
</header>
<nav>
<a href="main-production-list">Main Production List</a>
<a href="production-search">Search</a>
<a href="new-production">Add Production</a>
</nav>
@Body
<footer>
Footer of Productions Layout
</footer>
Markup HTML yang dirender berikut diproduksi oleh tata letak berlapis sebelumnya. Markup asing tidak muncul untuk fokus pada konten berlapis yang disediakan oleh tiga komponen yang terlibat:
- Elemen header (
<header>...</header>
), bilah navigasi produksi (<nav>...</nav>
), dan footer (<footer>...</footer>
) dan kontennya berasal dariProductionsLayout
komponen. - Judul "database" H1 (
<h1>...</h1>
), bilah navigasi episode (<nav>...</nav>
), dan informasi merek dagang (<div>...</div>
) berasal dariDoctorWhoLayout
komponen. - Judul "episode" H2 (
<h2>...</h2>
) dan daftar episode (<ul>...</ul>
) berasal dariEpisodes
komponen.
<header>
...
</header>
<nav>
<a href="main-production-list">Main Production List</a>
<a href="production-search">Search</a>
<a href="new-production">Add Production</a>
</nav>
<h1>...</h1>
<nav>
<a href="main-episode-list">Main Episode List</a>
<a href="episode-search">Search</a>
<a href="new-episode">Add Episode</a>
</nav>
<h2>...</h2>
<ul>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
<div>
...
</div>
<footer>
...
</footer>
Razor Berbagi tata letak Halaman dengan komponen terintegrasi
Saat komponen yang dapat dirutekan diintegrasikan ke dalam Razor aplikasi Pages, tata letak bersama aplikasi dapat digunakan dengan komponen. Untuk informasi selengkapnya, lihat Mengintegrasikan komponen ASP.NET Core Razor ke dalam aplikasi ASP.NET Core.
Saat komponen yang dapat dirutekan diintegrasikan ke dalam Razor aplikasi Pages, tata letak bersama aplikasi dapat digunakan dengan komponen. Untuk informasi selengkapnya, lihat Merender dan mengintegrasikan komponen ASP.NET CoreRazor.
Bagian
Untuk mengontrol konten dalam tata letak dari komponen anakRazor, lihat bagian ASP.NET CoreBlazor.
Sumber Daya Tambahan:
- Tata letak di ASP.NET Core
- Blazorsampel repositori GitHub () (
dotnet/blazor-samples
cara mengunduh)
ASP.NET Core