Memanggil API web dari 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 memanggil API web dari aplikasi Blazor .
Paket
Paket ini System.Net.Http.Json
menyediakan metode ekstensi untuk System.Net.Http.HttpClient dan System.Net.Http.HttpContent yang melakukan serialisasi dan deserialisasi otomatis menggunakan System.Text.Json
. Paket System.Net.Http.Json
disediakan oleh kerangka kerja bersama .NET dan tidak memerlukan penambahan referensi paket ke aplikasi.
Aplikasi sampel
Lihat contoh aplikasi di dotnet/blazor-samples
repositori GitHub.
BlazorWebAppCallWebApi
Panggil API web daftar todo eksternal (bukan di Blazor Web App) dari Blazor Web App:
Backend
: Aplikasi API web untuk mempertahankan daftar todo, berdasarkan API Minimal. Aplikasi API web adalah aplikasi terpisah dari Blazor Web App, mungkin dihosting di server yang berbeda.BlazorApp
/BlazorApp.Client
: Yang Blazor Web App memanggil aplikasi API web dengan HttpClient operasi daftar todo, seperti membuat, membaca, memperbarui, dan menghapus item (CRUD) dari daftar todo.
Untuk penyajian sisi klien (CSR), yang mencakup komponen Interactive WebAssembly dan komponen Otomatis yang telah mengadopsi CSR, panggilan dilakukan dengan yang telah dikonfigurasi HttpClient sebelumnya yang terdaftar dalam Program
file proyek klien (BlazorApp.Client
):
builder.Services.AddScoped(sp =>
new HttpClient
{
BaseAddress = new Uri(builder.Configuration["FrontendUrl"] ?? "https://localhost:5002")
});
Untuk penyajian sisi server (SSR), yang mencakup komponen Server prarender dan interaktif, komponen WebAssembly yang telah dirender sebelumnya, dan komponen Otomatis yang telah dirender atau telah mengadopsi SSR, panggilan dilakukan dengan HttpClient yang terdaftar dalam Program
file proyek server (BlazorApp
):
builder.Services.AddHttpClient();
Panggil API daftar film internal (di dalam Blazor Web App) tempat API berada di proyek Blazor Web Appserver :
BlazorApp
: Yang Blazor Web App mempertahankan daftar film:- Saat operasi dilakukan pada daftar film dalam aplikasi di server, panggilan API biasa digunakan.
- Saat panggilan API dilakukan oleh klien berbasis web, API web digunakan untuk operasi daftar film, berdasarkan API Minimal.
BlazorApp.Client
: Proyek klien dari Blazor Web App, yang berisi komponen Interactive WebAssembly dan Auto untuk manajemen pengguna daftar film.
Untuk CSR, yang mencakup komponen Interactive WebAssembly dan komponen Otomatis yang telah mengadopsi CSR, panggilan ke API dilakukan melalui layanan berbasis klien (ClientMovieService
) yang menggunakan yang telah dikonfigurasi HttpClient sebelumnya yang terdaftar dalam Program
file proyek klien (BlazorApp.Client
). Karena panggilan ini dilakukan melalui web publik atau privat, API daftar film adalah API web.
Contoh berikut mendapatkan daftar film dari /movies
titik akhir:
public class ClientMovieService(HttpClient http) : IMovieService
{
public async Task<Movie[]> GetMoviesAsync(bool watchedMovies) =>
await http.GetFromJsonAsync<Movie[]>("movies") ?? [];
}
Untuk SSR, yang mencakup komponen Server prarender dan interaktif, komponen WebAssembly yang telah dirender sebelumnya, dan komponen Otomatis yang telah dirender atau telah mengadopsi SSR, panggilan dilakukan langsung melalui layanan berbasis server (ServerMovieService
). API tidak mengandalkan jaringan, jadi ini adalah API standar untuk operasi CRUD daftar film.
Contoh berikut mendapatkan daftar film:
public class ServerMovieService(MovieContext db) : IMovieService
{
public async Task<Movie[]> GetMoviesAsync(bool watchedMovies) =>
watchedMovies ?
await db.Movies.Where(t => t.IsWatched).ToArrayAsync() :
await db.Movies.ToArrayAsync();
}
BlazorWebAppCallWebApi_Weather
Aplikasi sampel data cuaca yang menggunakan penyajian streaming untuk data cuaca.
BlazorWebAssemblyCallWebApi
Memanggil API web daftar todo dari Blazor WebAssembly aplikasi:
Backend
: Aplikasi API web untuk mempertahankan daftar todo, berdasarkan API Minimal.BlazorTodo
: Aplikasi Blazor WebAssembly yang memanggil API web dengan yang telah dikonfigurasi HttpClient sebelumnya untuk operasi CRUD daftar todo.
Skenario sisi server untuk memanggil API web eksternal
Komponen berbasis server memanggil API web eksternal menggunakan HttpClient instans, biasanya dibuat menggunakan IHttpClientFactory. Untuk panduan yang berlaku untuk aplikasi sisi server, lihat Membuat permintaan HTTP menggunakan IHttpClientFactory di ASP.NET Core.
Aplikasi sisi server tidak menyertakan HttpClient layanan. HttpClient Berikan ke aplikasi menggunakan HttpClient
infrastruktur pabrik.
Dalam file Program
:
builder.Services.AddHttpClient();
Komponen berikut Razor membuat permintaan ke API web untuk cabang GitHub yang mirip dengan contoh Penggunaan Dasar dalam artikel Membuat permintaan HTTP menggunakan IHttpClientFactory di ASP.NET Core .
CallWebAPI.razor
:
@page "/call-web-api"
@using System.Text.Json
@using System.Text.Json.Serialization
@inject IHttpClientFactory ClientFactory
<h1>Call web API from a Blazor Server Razor component</h1>
@if (getBranchesError || branches is null)
{
<p>Unable to get branches from GitHub. Please try again later.</p>
}
else
{
<ul>
@foreach (var branch in branches)
{
<li>@branch.Name</li>
}
</ul>
}
@code {
private IEnumerable<GitHubBranch>? branches = [];
private bool getBranchesError;
private bool shouldRender;
protected override bool ShouldRender() => shouldRender;
protected override async Task OnInitializedAsync()
{
var request = new HttpRequestMessage(HttpMethod.Get,
"https://api.github.com/repos/dotnet/AspNetCore.Docs/branches");
request.Headers.Add("Accept", "application/vnd.github.v3+json");
request.Headers.Add("User-Agent", "HttpClientFactory-Sample");
var client = ClientFactory.CreateClient();
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
using var responseStream = await response.Content.ReadAsStreamAsync();
branches = await JsonSerializer.DeserializeAsync
<IEnumerable<GitHubBranch>>(responseStream);
}
else
{
getBranchesError = true;
}
shouldRender = true;
}
public class GitHubBranch
{
[JsonPropertyName("name")]
public string? Name { get; set; }
}
}
Dalam contoh sebelumnya untuk C# 12 atau yang lebih baru, array kosong ([]
) dibuat untuk branches
variabel . Untuk versi C#yang lebih lama, buat array kosong (Array.Empty<GitHubBranch>()
).
Untuk contoh kerja tambahan, lihat contoh unggahan file sisi server yang mengunggah file ke pengontrol API web di artikel unggahan file ASP.NET CoreBlazor.
Abstraksi layanan untuk panggilan API web
Bagian ini berlaku untuk Blazor Web Appyang mempertahankan API web di proyek server atau mengubah panggilan API web ke API web eksternal.
Saat menggunakan mode render WebAssembly dan Auto interaktif, komponen dirender secara default. Komponen otomatis juga awalnya dirender secara interaktif dari server sebelum Blazor bundel diunduh ke klien dan runtime sisi klien diaktifkan. Ini berarti bahwa komponen yang menggunakan mode render ini harus dirancang sehingga berhasil berjalan dari klien dan server. Jika komponen harus memanggil API berbasis proyek server atau mengubah permintaan ke API web eksternal (yang berada di luar Blazor Web App) saat berjalan pada klien, pendekatan yang direkomendasikan adalah mengabstraksi panggilan API tersebut di belakang antarmuka layanan dan menerapkan versi klien dan server layanan:
- Versi klien memanggil API web dengan yang telah dikonfigurasi sebelumnya HttpClient.
- Versi server biasanya dapat mengakses sumber daya sisi server secara langsung. Menyuntikkan HttpClient di server yang melakukan panggilan kembali ke server tidak disarankan, karena permintaan jaringan biasanya tidak perlu. Atau, API mungkin berada di luar proyek server, tetapi abstraksi layanan untuk server diperlukan untuk mengubah permintaan dalam beberapa cara, misalnya untuk menambahkan token akses ke permintaan yang diproksi.
Saat menggunakan mode render WebAssembly, Anda juga memiliki opsi untuk menonaktifkan prarendering, sehingga komponen hanya dirender dari klien. Untuk informasi selengkapnya, lihat mode render ASP.NET CoreBlazor.
Contoh (aplikasi sampel):
- API web daftar film di
BlazorWebAppCallWebApi
aplikasi sampel. - Streaming merender API web data cuaca di
BlazorWebAppCallWebApi_Weather
aplikasi sampel. - Data cuaca dikembalikan ke klien dalam
BlazorWebAppOidc
aplikasi sampel (pola non-BFF) atauBlazorWebAppOidcBff
(pola BFF). Aplikasi ini menunjukkan panggilan API yang aman (web). Untuk informasi selengkapnya, lihat Mengamankan ASP.NET Core Blazor Web App dengan OpenID Connect (OIDC).
Blazor Web App API web eksternal
Bagian ini berlaku untuk Blazor Web Apps yang memanggil API web yang dikelola oleh proyek terpisah (eksternal), mungkin dihosting di server yang berbeda.
Blazor Web Apps biasanya merender komponen WebAssembly sisi klien, dan Komponen otomatis dirender di server selama penyajian sisi server (SSR) statis atau interaktif. HttpClient layanan tidak terdaftar secara default dalam Blazor Web Appproyek utama. Jika aplikasi hanya dijalankan dengan HttpClient layanan yang terdaftar dalam .Client
proyek, seperti yang dijelaskan di bagian Tambahkan HttpClient
layanan , menjalankan aplikasi menghasilkan kesalahan runtime:
InvalidOperationException: Tidak dapat memberikan nilai untuk properti 'Http' pada jenis '... {COMPONENT}'. Tidak ada layanan terdaftar jenis 'System.Net.Http.HttpClient'.
Gunakan salah satu pendekatan berikut:
HttpClient Tambahkan layanan ke proyek server untuk membuat HttpClient tersedia selama SSR. Gunakan pendaftaran layanan berikut dalam file proyek
Program
server:builder.Services.AddHttpClient();
HttpClient layanan disediakan oleh kerangka kerja bersama, sehingga referensi paket dalam file proyek aplikasi tidak diperlukan.
Contoh: Todo mencantumkan API web di
BlazorWebAppCallWebApi
aplikasi sampelJika pra-penyajian tidak diperlukan untuk komponen WebAssembly yang memanggil API web, nonaktifkan pra-penyajian dengan mengikuti panduan dalam mode render ASP.NET CoreBlazor. Jika Anda mengadopsi pendekatan ini, Anda tidak perlu menambahkan HttpClient layanan ke proyek Blazor Web App utama karena komponen tidak dirender di server.
Untuk informasi selengkapnya, lihat Layanan sisi klien gagal diselesaikan selama pra-penyajian.
Data yang telah dirender sebelumnya
Saat melakukan pra-penyajian, komponen merender dua kali: pertama secara statis, lalu secara interaktif. Status tidak secara otomatis mengalir dari komponen yang telah dirender ke komponen interaktif. Jika komponen melakukan operasi inisialisasi asinkron dan merender konten yang berbeda untuk status yang berbeda selama inisialisasi, seperti "Memuat..." indikator kemajuan, Anda mungkin melihat kedipan ketika komponen merender dua kali.
Anda dapat mengatasinya dengan mengalirkan status yang telah dirender sebelumnya menggunakan API Status Komponen Persisten, yang ditunjukkan BlazorWebAppCallWebApi
dan BlazorWebAppCallWebApi_Weather
aplikasi sampel. Ketika komponen dirender secara interaktif, komponen dapat merender dengan cara yang sama menggunakan status yang sama. Namun, API saat ini tidak berfungsi dengan navigasi yang disempurnakan, yang dapat Anda kerjakan dengan menonaktifkan navigasi yang disempurnakan pada tautan ke halaman (data-enhanced-nav=false
). Untuk informasi selengkapnya, lihat sumber daya berikut:
HttpClient
Menambahkan layanan
Panduan di bagian ini berlaku untuk skenario sisi klien.
Komponen sisi klien memanggil API web menggunakan layanan yang telah dikonfigurasi HttpClient sebelumnya, yang berfokus pada pembuatan permintaan kembali ke server asal. Konfigurasi layanan tambahan HttpClient untuk API web lainnya dapat dibuat dalam kode pengembang. Permintaan terdiri menggunakan Blazor pembantu JSON atau dengan HttpRequestMessage. Permintaan dapat mencakup konfigurasi opsi Fetch API .
Contoh konfigurasi di bagian ini hanya berguna ketika satu API web dipanggil untuk satu HttpClient instans di aplikasi. Ketika aplikasi harus memanggil beberapa API web, masing-masing dengan alamat dasar dan konfigurasinya sendiri, Anda dapat mengadopsi pendekatan berikut, yang dibahas nanti dalam artikel ini:
- Dinamai
HttpClient
denganIHttpClientFactory
: Setiap API web diberikan nama yang unik. Saat kode aplikasi atau Razor komponen memanggil API web, ia menggunakan instans bernama HttpClient untuk melakukan panggilan. - Ditik
HttpClient
: Setiap API web ditik. Saat kode aplikasi atau Razor komponen memanggil API web, ia menggunakan instans yang ditik HttpClient untuk melakukan panggilan.
Program
Dalam file, tambahkan HttpClient layanan jika belum ada dari templat proyek yang Blazor digunakan untuk membuat aplikasi:
builder.Services.AddScoped(sp =>
new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});
Contoh sebelumnya mengatur alamat dasar dengan builder.HostEnvironment.BaseAddress
(IWebAssemblyHostEnvironment.BaseAddress), yang mendapatkan alamat dasar untuk aplikasi dan biasanya berasal dari <base>
nilai tag href
di halaman host.
Kasus penggunaan yang paling umum untuk menggunakan alamat dasar klien sendiri adalah:
- Proyek klien (
.Client
) dari Blazor Web App (.NET 8 atau yang lebih baru) melakukan panggilan API web dari komponen webAssembly atau kode yang berjalan pada klien di WebAssembly ke API di aplikasi server. - Proyek klien (Client) aplikasi yang dihosting Blazor WebAssembly melakukan panggilan API web ke proyek server (Server). Perhatikan bahwa templat proyek yang dihosting Blazor WebAssembly tidak lagi tersedia di .NET 8 atau yang lebih baru. Namun, aplikasi yang dihosting Blazor WebAssembly tetap didukung untuk .NET 8.
Jika Anda memanggil API web eksternal (tidak berada di ruang URL yang sama dengan aplikasi klien), atur URI ke alamat dasar API web. Contoh berikut mengatur alamat dasar API web ke https://localhost:5001
, tempat aplikasi API web terpisah berjalan dan siap merespons permintaan dari aplikasi klien:
builder.Services.AddScoped(sp =>
new HttpClient
{
BaseAddress = new Uri("https://localhost:5001")
});
Pembantu JSON
HttpClient tersedia sebagai layanan yang telah dikonfigurasi sebelumnya untuk membuat permintaan kembali ke server asal.
HttpClient dan pembantu JSON (System.Net.Http.Json.HttpClientJsonExtensions) juga digunakan untuk memanggil titik akhir API web pihak ketiga. HttpClientdiimplementasikan menggunakan Fetch API browser dan tunduk pada batasannya, termasuk penegakan kebijakan asal yang sama, yang dibahas nanti dalam artikel ini di bagian Berbagi Sumber Daya Lintas Asal (CORS).
Alamat dasar klien diatur ke alamat server asal. HttpClient Masukkan instans ke dalam komponen menggunakan direktif@inject
:
@using System.Net.Http
@inject HttpClient Http
System.Net.Http.Json Gunakan namespace layanan untuk akses ke HttpClientJsonExtensions, termasuk GetFromJsonAsync, , PutAsJsonAsyncdan PostAsJsonAsync:
@using System.Net.Http.Json
Bagian berikut mencakup pembantu JSON:
System.Net.Http termasuk metode tambahan untuk mengirim permintaan HTTP dan menerima respons HTTP, misalnya untuk mengirim permintaan DELETE. Untuk informasi selengkapnya, lihat bagian DELETE dan metode ekstensi tambahan.
GET dari JSON (GetFromJsonAsync
)
GetFromJsonAsync mengirim permintaan HTTP GET dan mengurai isi respons JSON untuk membuat objek.
Dalam kode komponen berikut, todoItems
ditampilkan oleh komponen. GetFromJsonAsync dipanggil ketika komponen selesai menginisialisasi (OnInitializedAsync
).
todoItems = await Http.GetFromJsonAsync<TodoItem[]>("todoitems");
POST sebagai JSON (PostAsJsonAsync
)
PostAsJsonAsync mengirim permintaan POST ke URI yang ditentukan yang berisi nilai yang diserialisasikan sebagai JSON dalam isi permintaan.
Dalam kode komponen berikut, newItemName
disediakan oleh elemen terikat komponen. Metode AddItem
ini dipicu dengan memilih <button>
elemen.
await Http.PostAsJsonAsync("todoitems", addItem);
PostAsJsonAsyncHttpResponseMessagemengembalikan . Untuk mendeserialisasi konten JSON dari pesan respons, gunakan ReadFromJsonAsync metode ekstensi. Contoh berikut membaca data cuaca JSON sebagai array:
var content = await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
Array.Empty<WeatherForecast>();
PUT sebagai JSON (PutAsJsonAsync
)
PutAsJsonAsync mengirim permintaan HTTP PUT dengan konten yang dikodekan JSON.
Dalam kode komponen berikut, editItem
nilai untuk Name
dan IsCompleted
disediakan oleh elemen terikat dari komponen. Item Id
diatur ketika item dipilih di bagian lain dari UI (tidak ditampilkan) dan EditItem
dipanggil. Metode SaveItem
ini dipicu dengan memilih <button>
elemen . Contoh berikut tidak menunjukkan pemuatan todoItems
untuk brevity. Lihat bagian GET dari JSON (GetFromJsonAsync
) untuk contoh memuat item.
await Http.PutAsJsonAsync($"todoitems/{editItem.Id}", editItem);
PutAsJsonAsyncHttpResponseMessagemengembalikan . Untuk mendeserialisasi konten JSON dari pesan respons, gunakan ReadFromJsonAsync metode ekstensi. Contoh berikut membaca data cuaca JSON sebagai array:
var content = await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
Array.Empty<WeatherForecast>();
PATCH sebagai JSON (PatchAsJsonAsync
)
PatchAsJsonAsync mengirim permintaan PATCH HTTP dengan konten yang dikodekan JSON.
Catatan
Untuk informasi selengkapnya, lihat JsonPatch di API web ASP.NET Core.
Dalam contoh berikut, PatchAsJsonAsync menerima dokumen PATCH JSON sebagai string teks biasa dengan tanda kutip yang diloloskan:
await Http.PatchAsJsonAsync(
$"todoitems/{id}",
"[{\"operationType\":2,\"path\":\"/IsComplete\",\"op\":\"replace\",\"value\":true}]");
PatchAsJsonAsyncHttpResponseMessagemengembalikan . Untuk mendeserialisasi konten JSON dari pesan respons, gunakan ReadFromJsonAsync metode ekstensi. Contoh berikut membaca data item todo JSON sebagai array. Array kosong dibuat jika tidak ada data item yang dikembalikan oleh metode , jadi content
tidak null setelah pernyataan dijalankan:
var response = await Http.PatchAsJsonAsync(...);
var content = await response.Content.ReadFromJsonAsync<TodoItem[]>() ??
Array.Empty<TodoItem>();
Ditata dengan indentasi, spasi, dan tanda kutip yang tidak dilewati, dokumen PATCH yang tidak dikodekan muncul sebagai JSON berikut:
[
{
"operationType": 2,
"path": "/IsComplete",
"op": "replace",
"value": true
}
]
Untuk menyederhanakan pembuatan dokumen PATCH di aplikasi yang mengeluarkan permintaan PATCH, aplikasi dapat menggunakan dukungan .NET JSON PATCH, seperti yang ditunjukkan panduan berikut.
Microsoft.AspNetCore.JsonPatch
Instal paket NuGet dan gunakan fitur API paket untuk menyusun JsonPatchDocument permintaan PATCH.
Catatan
Untuk panduan tentang menambahkan paket ke aplikasi .NET, lihat artikel di bagian Menginstal dan mengelola paket di Alur kerja konsumsi paket (dokumentasi NuGet). Konfirmasikan versi paket yang benar di NuGet.org.
Tambahkan @using
direktif untuk System.Text.Jsonnamespace , System.Text.Json.Serialization, dan Microsoft.AspNetCore.JsonPatch ke bagian Razor atas komponen:
@using System.Text.Json
@using System.Text.Json.Serialization
@using Microsoft.AspNetCore.JsonPatch
JsonPatchDocument Buat untuk dengan IsComplete
diatur TodoItem
ke true
menggunakan Replace metode :
var patchDocument = new JsonPatchDocument<TodoItem>()
.Replace(p => p.IsComplete, true);
Teruskan operasi dokumen (patchDocument.Operations
) ke PatchAsJsonAsync panggilan:
private async Task UpdateItem(long id)
{
await Http.PatchAsJsonAsync(
$"todoitems/{id}",
patchDocument.Operations,
new JsonSerializerOptions()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
});
}
JsonSerializerOptions.DefaultIgnoreCondition diatur ke JsonIgnoreCondition.WhenWritingDefault untuk mengabaikan properti hanya jika sama dengan nilai default untuk jenisnya.
Tambahkan JsonSerializerOptions.WriteIndented atur ke true
jika Anda ingin menyajikan payload JSON dalam format yang menyenangkan untuk ditampilkan. Menulis JSON yang diindentasi tidak memiliki bantalan untuk memproses permintaan PATCH dan biasanya tidak dilakukan di aplikasi produksi untuk permintaan API web.
Ikuti panduan di artikel JsonPatch di API web ASP.NET Core untuk menambahkan tindakan pengontrol PATCH ke API web. Atau, pemrosesan permintaan PATCH dapat diimplementasikan sebagai API Minimal dengan langkah-langkah berikut.
Tambahkan referensi paket untuk Microsoft.AspNetCore.Mvc.NewtonsoftJson
paket NuGet ke aplikasi API web.
Catatan
Tidak perlu menambahkan referensi paket untuk Microsoft.AspNetCore.JsonPatch
paket ke aplikasi karena referensi ke Microsoft.AspNetCore.Mvc.NewtonsoftJson
paket secara otomatis menambahkan referensi paket untuk Microsoft.AspNetCore.JsonPatch
.
Program
Dalam file tambahkan @using
direktif untuk Microsoft.AspNetCore.JsonPatch namespace:
using Microsoft.AspNetCore.JsonPatch;
Berikan titik akhir ke alur pemrosesan permintaan API web:
app.MapPatch("/todoitems/{id}", async (long id, TodoContext db) =>
{
if (await db.TodoItems.FindAsync(id) is TodoItem todo)
{
var patchDocument =
new JsonPatchDocument<TodoItem>().Replace(p => p.IsComplete, true);
patchDocument.ApplyTo(todo);
await db.SaveChangesAsync();
return TypedResults.Ok(todo);
}
return TypedResults.NoContent();
});
Peringatan
Seperti contoh lain dalam artikel JsonPatch di api web ASP.NET Core, API PATCH sebelumnya tidak melindungi API web dari serangan posting berlebihan. Untuk informasi selengkapnya, lihat Tutorial: Membuat API web dengan ASP.NET Core.
Untuk pengalaman PATCH yang sepenuhnya berfungsi, lihat BlazorWebAppCallWebApi
aplikasi sampel.
DELETE (DeleteAsync
) dan metode ekstensi tambahan
System.Net.Http termasuk metode ekstensi tambahan untuk mengirim permintaan HTTP dan menerima respons HTTP. HttpClient.DeleteAsync digunakan untuk mengirim permintaan HTTP DELETE ke API web.
Dalam kode komponen berikut, <button>
elemen memanggil DeleteItem
metode . Elemen terikat <input>
memasok id
item yang akan dihapus.
await Http.DeleteAsync($"todoitems/{id}");
Dinamai HttpClient
dengan IHttpClientFactory
IHttpClientFactory layanan dan konfigurasi bernama HttpClient didukung.
Catatan
Alternatif untuk menggunakan nama HttpClient dari adalah IHttpClientFactory menggunakan yang ditik HttpClient. Untuk informasi selengkapnya, lihat bagian Jenis HttpClient
.
Microsoft.Extensions.Http
Tambahkan paket NuGet ke aplikasi.
Catatan
Untuk panduan tentang menambahkan paket ke aplikasi .NET, lihat artikel di bagian Menginstal dan mengelola paket di Alur kerja konsumsi paket (dokumentasi NuGet). Konfirmasikan versi paket yang benar di NuGet.org.
Program
Dalam file proyek klien:
builder.Services.AddHttpClient("WebAPI", client =>
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
Jika klien bernama akan digunakan oleh komponen sisi klien yang Blazor Web Apptelah dirender sebelumnya dari , pendaftaran layanan sebelumnya akan muncul di proyek server dan .Client
proyek. Di server, builder.HostEnvironment.BaseAddress
digantikan oleh alamat dasar API web, yang dijelaskan lebih lanjut di bawah ini.
Contoh sisi klien sebelumnya mengatur alamat dasar dengan builder.HostEnvironment.BaseAddress
(IWebAssemblyHostEnvironment.BaseAddress), yang mendapatkan alamat dasar untuk aplikasi sisi klien dan biasanya berasal dari <base>
nilai tag href
di halaman host.
Kasus penggunaan yang paling umum untuk menggunakan alamat dasar klien sendiri adalah:
- Proyek klien (
.Client
) dari Blazor Web App yang melakukan panggilan API web dari komponen WebAssembly/Auto atau kode yang berjalan pada klien di WebAssembly ke API di aplikasi server di alamat host yang sama. - Proyek klien (Client) dari aplikasi yang dihosting Blazor WebAssembly yang melakukan panggilan API web ke proyek server (Server).
Kasus penggunaan yang paling umum untuk menggunakan alamat dasar klien sendiri ada di proyek klien (Client) aplikasi yang dihosting Blazor WebAssembly yang melakukan panggilan API web ke proyek server (Server).
Jika Anda memanggil API web eksternal (bukan di ruang URL yang sama dengan aplikasi klien) atau Anda mengonfigurasi layanan di aplikasi sisi server (misalnya untuk menangani pra-penyajian komponen sisi klien di server), atur URI ke alamat dasar API web. Contoh berikut mengatur alamat dasar API web ke https://localhost:5001
, tempat aplikasi API web terpisah berjalan dan siap merespons permintaan dari aplikasi klien:
builder.Services.AddHttpClient("WebAPI", client =>
client.BaseAddress = new Uri("https://localhost:5001"));
Dalam kode komponen berikut:
- Instans IHttpClientFactory membuat bernama HttpClient.
- Nama HttpClient digunakan untuk mengeluarkan permintaan GET untuk data prakiraan cuaca JSON dari API web di
/forecast
.
@inject IHttpClientFactory ClientFactory
...
@code {
private Forecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
var client = ClientFactory.CreateClient("WebAPI");
forecasts = await client.GetFromJsonAsync<Forecast[]>("forecast") ?? [];
}
}
Aplikasi BlazorWebAppCallWebApi
sampel menunjukkan panggilan API web dengan nama HttpClient dalam komponennyaCallTodoWebApiCsrNamedClient
. Untuk demonstrasi kerja tambahan di aplikasi klien berdasarkan panggilan Microsoft Graph dengan nama HttpClient, lihat Menggunakan Graph API dengan ASP.NET Core Blazor WebAssembly.
Untuk demonstrasi yang berfungsi di aplikasi klien berdasarkan panggilan Microsoft Graph dengan nama HttpClient, lihat Menggunakan Graph API dengan ASP.NET Core Blazor WebAssembly.
Diketik HttpClient
HttpClient Diketik menggunakan satu atau beberapa instans aplikasiHttpClient, default atau bernama, untuk mengembalikan data dari satu atau beberapa titik akhir API web.
Catatan
Alternatif untuk menggunakan jenis HttpClient adalah menggunakan bernama HttpClient dari IHttpClientFactory. Untuk informasi selengkapnya, lihat bagian Bernama HttpClient
dengan IHttpClientFactory
.
Microsoft.Extensions.Http
Tambahkan paket NuGet ke aplikasi.
Catatan
Untuk panduan tentang menambahkan paket ke aplikasi .NET, lihat artikel di bagian Menginstal dan mengelola paket di Alur kerja konsumsi paket (dokumentasi NuGet). Konfirmasikan versi paket yang benar di NuGet.org.
Contoh berikut mengeluarkan permintaan GET untuk data prakiraan cuaca JSON dari API web di /forecast
.
ForecastHttpClient.cs
:
using System.Net.Http.Json;
namespace BlazorSample.Client;
public class ForecastHttpClient(HttpClient http)
{
public async Task<Forecast[]> GetForecastAsync() =>
await http.GetFromJsonAsync<Forecast[]>("forecast") ?? [];
}
Program
Dalam file proyek klien:
builder.Services.AddHttpClient<ForecastHttpClient>(client =>
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
Jika klien yang di ketik akan digunakan oleh komponen sisi klien yang Blazor Web Apptelah dirender sebelumnya dari , pendaftaran layanan sebelumnya akan muncul di proyek server dan .Client
proyek. Di server, builder.HostEnvironment.BaseAddress
digantikan oleh alamat dasar API web, yang dijelaskan lebih lanjut di bawah ini.
Contoh sebelumnya mengatur alamat dasar dengan builder.HostEnvironment.BaseAddress
(IWebAssemblyHostEnvironment.BaseAddress), yang mendapatkan alamat dasar untuk aplikasi sisi klien dan biasanya berasal dari <base>
nilai tag href
di halaman host.
Kasus penggunaan yang paling umum untuk menggunakan alamat dasar klien sendiri adalah:
- Proyek klien (
.Client
) dari Blazor Web App yang melakukan panggilan API web dari komponen WebAssembly/Auto atau kode yang berjalan pada klien di WebAssembly ke API di aplikasi server di alamat host yang sama. - Proyek klien (Client) dari aplikasi yang dihosting Blazor WebAssembly yang melakukan panggilan API web ke proyek server (Server).
Kasus penggunaan yang paling umum untuk menggunakan alamat dasar klien sendiri ada di proyek klien (Client) aplikasi yang dihosting Blazor WebAssembly yang melakukan panggilan API web ke proyek server (Server).
Jika Anda memanggil API web eksternal (bukan di ruang URL yang sama dengan aplikasi klien) atau Anda mengonfigurasi layanan di aplikasi sisi server (misalnya untuk menangani pra-penyajian komponen sisi klien di server), atur URI ke alamat dasar API web. Contoh berikut mengatur alamat dasar API web ke https://localhost:5001
, tempat aplikasi API web terpisah berjalan dan siap merespons permintaan dari aplikasi klien:
builder.Services.AddHttpClient<ForecastHttpClient>(client =>
client.BaseAddress = new Uri("https://localhost:5001"));
Komponen menyuntikkan yang ditik HttpClient untuk memanggil API web.
Dalam kode komponen berikut:
- Instans sebelumnya disuntikkan
ForecastHttpClient
, yang membuat jenis HttpClient. - HttpClient Jenis digunakan untuk mengeluarkan permintaan GET untuk data prakiraan cuaca JSON dari API web.
@inject ForecastHttpClient Http
...
@code {
private Forecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await Http.GetForecastAsync();
}
}
Aplikasi BlazorWebAppCallWebApi
sampel menunjukkan panggilan API web dengan yang diketik HttpClient dalam komponennyaCallTodoWebApiCsrTypedClient
. Perhatikan bahwa komponen mengadopsi dan penyajian sisi klien (CSR) (InteractiveWebAssembly
mode render) dengan pra-penyajian, sehingga pendaftaran layanan klien yang ditik muncul dalam Program
file proyek server dan .Client
proyek.
Cookiekredensial permintaan berbasis
Panduan di bagian ini berlaku untuk skenario sisi klien yang mengandalkan autentikasi cookie.
Untuk cookieautentikasi berbasis, yang dianggap lebih aman daripada autentikasi token pembawa, cookie kredensial dapat dikirim dengan setiap permintaan API web dengan memanggil AddHttpMessageHandler dengan DelegatingHandler pada yang telah dikonfigurasi sebelumnya HttpClient. Handler mengonfigurasi SetBrowserRequestCredentials dengan BrowserRequestCredentials.Include, yang menyarankan browser untuk mengirim kredensial dengan setiap permintaan, seperti cookie atau header autentikasi HTTP, termasuk untuk permintaan lintas asal.
CookieHandler.cs
:
public class CookieHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
request.Headers.Add("X-Requested-With", ["XMLHttpRequest"]);
return base.SendAsync(request, cancellationToken);
}
}
CookieHandler
terdaftar dalam Program
file:
builder.Services.AddTransient<CookieHandler>();
Handler pesan ditambahkan ke prakonfigurasi HttpClient apa pun yang memerlukan cookie autentikasi:
builder.Services.AddHttpClient(...)
.AddHttpMessageHandler<CookieHandler>();
Untuk demonstrasi, lihat Mengamankan ASP.NET Core Blazor WebAssembly dengan ASP.NET Core Identity.
Saat menyusun HttpRequestMessage, atur kredensial dan header permintaan browser secara langsung:
var requestMessage = new HttpRequestMessage() { ... };
requestMessage.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
requestMessage.Headers.Add("X-Requested-With", ["XMLHttpRequest"]);
HttpClient
dan HttpRequestMessage
dengan opsi permintaan Fetch API
Panduan di bagian ini berlaku untuk skenario sisi klien yang mengandalkan autentikasi token pembawa.
HttpClient
(Dokumentasi API) dan HttpRequestMessage dapat digunakan untuk menyesuaikan permintaan. Misalnya, Anda dapat menentukan metode HTTP dan header permintaan. Komponen berikut membuat POST
permintaan ke titik akhir API web dan menunjukkan isi respons.
TodoRequest.razor
:
@page "/todo-request"
@using System.Net.Http.Headers
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject HttpClient Http
@inject IAccessTokenProvider TokenProvider
<h1>ToDo Request</h1>
<h1>ToDo Request Example</h1>
<button @onclick="PostRequest">Submit POST request</button>
<p>Response body returned by the server:</p>
<p>@responseBody</p>
@code {
private string? responseBody;
private async Task PostRequest()
{
var requestMessage = new HttpRequestMessage()
{
Method = new HttpMethod("POST"),
RequestUri = new Uri("https://localhost:10000/todoitems"),
Content =
JsonContent.Create(new TodoItem
{
Name = "My New Todo Item",
IsComplete = false
})
};
var tokenResult = await TokenProvider.RequestAccessToken();
if (tokenResult.TryGetToken(out var token))
{
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", token.Value);
requestMessage.Content.Headers.TryAddWithoutValidation(
"x-custom-header", "value");
var response = await Http.SendAsync(requestMessage);
var responseStatusCode = response.StatusCode;
responseBody = await response.Content.ReadAsStringAsync();
}
}
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
}
BlazorImplementasi sisi klien dari HttpClient penggunaan Fetch API dan mengonfigurasi opsi Fetch API khusus permintaan yang mendasar melalui HttpRequestMessage metode ekstensi dan WebAssemblyHttpRequestMessageExtensions. Atur opsi tambahan menggunakan metode ekstensi generik SetBrowserRequestOption . Blazor dan Fetch API yang mendasar tidak langsung menambahkan atau mengubah header permintaan. Untuk informasi selengkapnya tentang bagaimana agen pengguna, seperti browser, berinteraksi dengan header, lihat kumpulan dokumentasi agen pengguna eksternal dan sumber daya web lainnya.
Respons HTTP biasanya di-buffer untuk mengaktifkan dukungan untuk pembacaan sinkron pada konten respons. Untuk mengaktifkan dukungan untuk streaming respons, gunakan SetBrowserResponseStreamingEnabled metode ekstensi pada permintaan.
Untuk menyertakan kredensial dalam permintaan lintas asal, gunakan SetBrowserRequestCredentials metode ekstensi:
requestMessage.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
Untuk informasi selengkapnya tentang opsi Fetch API, lihat dokumen web MDN: WindowOrWorkerGlobalScope.fetch(): Parameter.
Menangani kesalahan
Menangani kesalahan respons API web dalam kode pengembang saat terjadi. Misalnya, GetFromJsonAsync mengharapkan respons JSON dari API web dengan Content-Type
.application/json
Jika respons tidak dalam format JSON, validasi konten akan menampilkan NotSupportedException.
Dalam contoh berikut, titik akhir URI untuk permintaan data prakiraan cuaca salah eja. URI harus tetapi WeatherForecast
muncul dalam panggilan sebagai WeatherForcast
, yang tidak memiliki huruf e
di Forecast
.
Panggilan GetFromJsonAsync mengharapkan JSON dikembalikan, tetapi API web mengembalikan HTML untuk pengecualian yang tidak tertangani dengan Content-Type
.text/html
Pengecualian yang tidak tertangani terjadi karena jalur ke /WeatherForcast
tidak ditemukan dan middleware tidak dapat melayani halaman atau tampilan untuk permintaan tersebut.
Pada OnInitializedAsync klien, NotSupportedException dilemparkan ketika konten respons divalidasi sebagai non-JSON. Pengecualian tertangkap dalam blok, di catch
mana logika kustom dapat mencatat kesalahan atau menyajikan pesan kesalahan yang mudah diingat kepada pengguna.
ReturnHTMLOnException.razor
:
@page "/return-html-on-exception"
@using {PROJECT NAME}.Shared
@inject HttpClient Http
<h1>Fetch data but receive HTML on unhandled exception</h1>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<h2>Temperatures by Date</h2>
<ul>
@foreach (var forecast in forecasts)
{
<li>
@forecast.Date.ToShortDateString():
@forecast.TemperatureC ℃
@forecast.TemperatureF ℉
</li>
}
</ul>
}
<p>
@exceptionMessage
</p>
@code {
private WeatherForecast[]? forecasts;
private string? exceptionMessage;
protected override async Task OnInitializedAsync()
{
try
{
// The URI endpoint "WeatherForecast" is misspelled on purpose on the
// next line. See the preceding text for more information.
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForcast");
}
catch (NotSupportedException exception)
{
exceptionMessage = exception.Message;
}
}
}
Catatan
Contoh sebelumnya adalah untuk tujuan demonstrasi. API web dapat dikonfigurasi untuk mengembalikan JSON bahkan ketika titik akhir tidak ada atau pengecualian yang tidak tertangani terjadi di server.
Untuk informasi selengkapnya, lihat Menangani kesalahan di aplikasi ASP.NET CoreBlazor.
Berbagi Sumber Daya Lintas Asal (CORS)
Keamanan browser membatasi halaman web membuat permintaan ke domain yang berbeda dari yang melayani halaman web. Pembatasan ini disebut kebijakan asal yang sama. Kebijakan asal yang sama membatasi (tetapi tidak mencegah) situs berbahaya membaca data sensitif dari situs lain. Untuk membuat permintaan dari browser ke titik akhir dengan asal yang berbeda, titik akhir harus mengaktifkan Berbagi Sumber Daya Lintas Asal (CORS).
Untuk informasi selengkapnya tentang CORS sisi server, lihat Mengaktifkan Permintaan Lintas Asal (CORS) di ASP.NET Core. Contoh artikel tidak berkaitan langsung dengan Razor skenario komponen, tetapi artikel ini berguna untuk mempelajari konsep CORS umum.
Untuk informasi tentang permintaan CORS sisi klien, lihat skenario keamanan tambahan ASP.NET CoreBlazor WebAssembly.
Dukungan antiforgery
Untuk menambahkan dukungan antiforgery ke permintaan HTTP, masukkan AntiforgeryStateProvider
dan tambahkan RequestToken
ke koleksi header sebagai RequestVerificationToken
:
@inject AntiforgeryStateProvider Antiforgery
private async Task OnSubmit()
{
var antiforgery = Antiforgery.GetAntiforgeryToken();
var request = new HttpRequestMessage(HttpMethod.Post, "action");
request.Headers.Add("RequestVerificationToken", antiforgery.RequestToken);
var response = await client.SendAsync(request);
...
}
Untuk informasi selengkapnya, lihat autentikasi dan otorisasi ASP.NET CoreBlazor.
Blazor contoh komponen kerangka kerja untuk menguji akses API web
Berbagai alat jaringan tersedia untuk umum untuk menguji aplikasi backend API web secara langsung, seperti Pengembang Browser Firefox. Blazor sumber referensi kerangka kerja mencakup HttpClient aset pengujian yang berguna untuk pengujian:
HttpClientTest
aset di repositori dotnet/aspnetcore
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).
Sumber Daya Tambahan:
Umum
- Cross-Origin Resource Sharing (CORS) di W3C
- Aktifkan Permintaan Lintas Asal (CORS) di ASP.NET Core: Meskipun konten berlaku untuk aplikasi ASP.NET Core, bukan Razor komponen, artikel ini mencakup konsep CORS umum.
Mitigasi serangan overposting
API Web dapat rentan terhadap serangan overposting, juga dikenal sebagai serangan penugasan massal. Serangan overposting terjadi ketika pengguna berbahaya mengeluarkan POST formulir HTML ke server yang memproses data untuk properti yang bukan bagian dari formulir yang dirender dan bahwa pengembang tidak ingin mengizinkan pengguna untuk memodifikasi. Istilah "overposting" secara harfiah berarti bahwa pengguna jahat memiliki over-POSTed dengan formulir .
Untuk panduan tentang mitigasi serangan overposting, lihat Tutorial: Membuat API web dengan ASP.NET Core.
Sisi server
- Skenario keamanan tambahan ASP.NET Core Blazor sisi server: Mencakup cakupan penggunaan HttpClient untuk membuat permintaan API web yang aman.
- Membuat permintaan HTTP menggunakan IHttpClientFactory di ASP.NET Core
- Menerapkan HTTPS di ASP.NET Core
- Kestrel Konfigurasi titik akhir HTTPS
Sisi klien
- ASP.NET Skenario keamanan tambahan CoreBlazor WebAssembly: Mencakup cakupan penggunaan HttpClient untuk membuat permintaan API web yang aman.
- Menggunakan API Graph dengan ASP.NET Core Blazor WebAssembly
- Ambil API
ASP.NET Core