Bagikan melalui


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.

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 Aplikasi Web) dari Blazor Aplikasi Web:

  • Backend: Aplikasi API web untuk mempertahankan daftar todo, berdasarkan API Minimal. Aplikasi API web adalah aplikasi terpisah dari Blazor Aplikasi Web, mungkin dihosting di server yang berbeda.
  • BlazorApp/BlazorApp.ClientBlazor: Aplikasi Web yang 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 Aplikasi Web), tempat API berada di proyek Blazor server Aplikasi Web:

  • BlazorAppBlazor: Aplikasi Web yang 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 Blazor klien Aplikasi Web, 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)
    {
        return 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)
    {
        return 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 secara default. 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 Apps yang 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 Aplikasi Web) saat berjalan pada klien, pendekatan yang disarankan adalah mengabstraksi panggilan API 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) atau BlazorWebAppOidcBff (pola BFF). Aplikasi ini menunjukkan panggilan API yang aman (web). Untuk informasi selengkapnya, lihat Mengamankan ASP.NET Core Blazor Web App dengan OpenID Koneksi (OIDC).

Blazor API web eksternal Aplikasi Web

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 proyek utama Aplikasi Web. 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();
    

    Tidak diperlukan referensi paket eksplisit karena HttpClient layanan disediakan oleh kerangka kerja bersama.

    Contoh: Todo mencantumkan API web di BlazorWebAppCallWebApiaplikasi sampel

  • Jika 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 utama Aplikasi Web karena komponen tidak akan 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_Weatheraplikasi 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 BlazorJSpembantu ON 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:

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) Blazor Aplikasi Web (.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")
    });

JSPembantu ON

HttpClient tersedia sebagai layanan yang telah dikonfigurasi sebelumnya untuk membuat permintaan kembali ke server asal.

HttpClient dan JSpembantu ON (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 JSisi respons ON 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 as JSON (PostAsJsonAsync)

PostAsJsonAsync mengirim permintaan POST ke URI yang ditentukan yang berisi nilai yang diserialisasikan sebagai JSAKTIF 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 JSkonten ON dari pesan respons, gunakan ReadFromJsonAsync metode ekstensi. Contoh berikut membaca JSdata cuaca ON sebagai array:

var content = await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ?? 
    Array.Empty<WeatherForecast>();

PUT AS JSON (PutAsJsonAsync)

PutAsJsonAsync mengirim permintaan HTTP PUT dengan JSkonten yang dikodekan ON.

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 JSkonten ON dari pesan respons, gunakan ReadFromJsonAsync metode ekstensi. Contoh berikut membaca JSdata cuaca ON sebagai array:

var content = await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ?? 
    Array.Empty<WeatherForecast>();

PATCH sebagai JSAKTIF (PatchAsJsonAsync)

PatchAsJsonAsync mengirim permintaan PATCH HTTP dengan JSkonten yang dikodekan ON.

Catatan

Untuk informasi selengkapnya, lihat JsonPatch di API web ASP.NET Core.

Dalam contoh berikut, PatchAsJsonAsync menerima JSdokumen ON PATCH sebagai string teks biasa dengan tanda kutip yang lolos:

await Http.PatchAsJsonAsync(
    $"todoitems/{id}", 
    "[{\"operationType\":2,\"path\":\"/IsComplete\",\"op\":\"replace\",\"value\":true}]");

PatchAsJsonAsyncHttpResponseMessagemengembalikan . Untuk mendeserialisasi JSkonten ON dari pesan respons, gunakan ReadFromJsonAsync metode ekstensi. Contoh berikut membaca JSdata item todo ON 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 ON berikut JS:

[
  {
    "operationType": 2,
    "path": "/IsComplete",
    "op": "replace",
    "value": true
  }
]

Untuk menyederhanakan pembuatan dokumen PATCH dalam 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 diatur ke true jika Anda ingin menyajikan JSpayload ON dalam format yang menyenangkan untuk ditampilkan. Menulis INDENTED JSON 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 BlazorWebAppCallWebApiaplikasi 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 telah dirender sebelumnya dari Aplikasi Web, 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) Blazor Aplikasi Web 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:

@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 JSdata prakiraan cuaca ON 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()
    {
        return 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 telah dirender sebelumnya dari Aplikasi Web, 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) Blazor Aplikasi Web 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 JSdata prakiraan cuaca ON 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.

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 cookieheader autentikasi s atau 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>();

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 JSrespons ON dari API web dengan Content-Type .application/json Jika respons tidak dalam JSformat ON, 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-AKTIFJS. 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 &#8451;
                @forecast.TemperatureF &#8457;
            </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

Sisi server

Sisi klien