Tutorial: Membuat permintaan di aplikasi konsol .NET menggunakan C#
Tutorial ini membuat aplikasi yang mengeluarkan permintaan HTTP ke layanan REST di GitHub. Aplikasi membaca informasi dalam format JSON dan mengubah JSON menjadi objek C#. Mengonversi dari objek JSON ke C# dikenal sebagai deserialisasi.
Tutorial ini menunjukkan cara:
- Mengirim permintaan.
- Melakukan deserialisasi respons JSON.
- Mengonfigurasi deserialisasi dengan atribut.
Jika Anda lebih suka mengikuti sampel akhir untuk tutorial ini, Anda dapat mengunduhnya. Untuk petunjuk pengunduhan, lihat Sampel dan Tutorial.
Prasyarat
- .NET SDK 6.0 atau yang lebih baru
- Editor kode seperti [Visual Studio Code (editor lintas platform sumber terbuka). Anda dapat menjalankan aplikasi sampel di Windows, Linux, atau macOS, atau dalam kontainer Docker.
Buat aplikasi klien
Buka perintah dan buat direktori baru untuk aplikasi Anda. Jadikan direktori baru tersebut direktori saat ini.
Masukkan perintah berikut di jendela konsol:
dotnet new console --name WebAPIClient
Perintah ini membuat file starter untuk aplikasi dasar "Halo Dunia". Nama proyeknya adalah "WebAPIClient".
Arahkan ke direktori "WebAPIClient", dan jalankan aplikasi.
cd WebAPIClient
dotnet run
dotnet run
secara otomatis menjalankandotnet restore
untuk memulihkan dependensi apa pun yang dibutuhkan aplikasi. Proyek tersebut juga menjalankandotnet build
jika diperlukan. Anda akan melihat output"Hello, World!"
aplikasi . Di terminal Anda, tekan Ctrl+C untuk menghentikan aplikasi.
Buat permintaan HTTP
Aplikasi ini memanggil GitHub API untuk mendapatkan informasi tentang proyek di bawah payung .NET Foundation. Titik akhirnya adalah https://api.github.com/orgs/dotnet/repos. Untuk mengambil informasi, itu membuat permintaan HTTP GET. Browser juga membuat permintaan HTTP GET, sehingga Anda dapat menempelkan URL tersebut ke bilah alamat browser untuk melihat informasi apa yang akan Anda terima dan proses.
Gunakan kelas HttpClient untuk membuat permintaan. HttpClient hanya mendukung metode asinkron untuk API yang berjalan lama. Jadi langkah-langkah berikut membuat metode asinkron dan memanggilnya dari metode Utama.
Program.cs
Buka file di direktori proyek Anda dan ganti kontennya dengan yang berikut ini:await ProcessRepositoriesAsync(); static async Task ProcessRepositoriesAsync(HttpClient client) { }
Kode ini:
- Mengganti pernyataan
Console.WriteLine
dengan panggilan keProcessRepositoriesAsync
yang menggunakan kata kunciawait
. - Mendefinisikan metode kosong
ProcessRepositoriesAsync
.
- Mengganti pernyataan
Program
Di kelas , gunakan HttpClient untuk menangani permintaan dan respons, dengan mengganti konten dengan C#berikut.using System.Net.Http.Headers; using HttpClient client = new(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter"); await ProcessRepositoriesAsync(client); static async Task ProcessRepositoriesAsync(HttpClient client) { }
Kode ini:
- Menyiapkan header HTTP untuk semua permintaan:
- Header
Accept
untuk menerima tanggapan JSON - Header
User-Agent
. Header ini diperiksa oleh kode server GitHub dan diperlukan untuk mengambil informasi dari GitHub.
- Header
- Menyiapkan header HTTP untuk semua permintaan:
Dalam metode
ProcessRepositoriesAsync
, panggil titik akhir GitHub yang mengembalikan daftar semua repositori di bawah organisasi .NET foundation:static async Task ProcessRepositoriesAsync(HttpClient client) { var json = await client.GetStringAsync( "https://api.github.com/orgs/dotnet/repos"); Console.Write(json); }
Kode ini:
- Menunggu tugas yang dikembalikan dari metode panggilan HttpClient.GetStringAsync(String) . Metode ini mengirimkan permintaan HTTP GET ke URI yang ditentukan. Isi respons dikembalikan sebagai String, yang tersedia saat tugas selesai.
- String
json
respons dicetak ke konsol.
Bangun aplikasi dan jalankan.
dotnet run
Tidak ada peringatan build karena
ProcessRepositoriesAsync
sekarang berisi operatorawait
. Outputnya adalah tampilan panjang teks JSON.
Deserialisasi Hasil JSON
Langkah-langkah berikut mengubah respons JSON menjadi objek C#. Anda menggunakan kelas System.Text.Json.JsonSerializer untuk membatalkan serialisasi JSON menjadi objek.
Buat file bernama Repository.cs dan tambahkan kode berikut:
public record class Repository(string name);
Kode sebelumnya mendefinisikan kelas untuk mewakili objek JSON yang dikembalikan dari GitHub API. Anda akan menggunakan kelas ini untuk menampilkan daftar nama repositori.
JSON untuk objek repositori berisi lusinan properti, tetapi hanya properti
name
yang akan dideserialisasi. Serializer secara otomatis mengabaikan properti JSON yang tidak cocok dengan kelas target. Fitur ini memudahkan untuk membuat jenis yang bekerja hanya dengan subset bidang dalam paket JSON yang besar.Konvensi C# adalah menggunakan huruf kapital pada huruf pertama dari nama properti , tetapi properti
name
di sini dimulai dengan huruf kecil karena sama persis dengan apa yang ada di JSON. Nanti Anda akan melihat cara menggunakan nama properti C# yang tidak cocok dengan nama properti JSON.Gunakan serializer untuk mengubah JSON menjadi objek C#. Ganti panggilan ke GetStringAsync(String) dalam metode
ProcessRepositoriesAsync
dengan baris berikut:await using Stream stream = await client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos"); var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(stream);
Kode yang diperbarui menggantikan GetStringAsync(String) dengan GetStreamAsync(String). Metode serializer ini menggunakan aliran alih-alih string sebagai sumbernya.
Argumen pertama untuk JsonSerializer.DeserializeAsync<TValue>(Stream, JsonSerializerOptions, CancellationToken) adalah ekspresi
await
.await
ekspresi dapat muncul hampir di mana saja dalam kode Anda, meskipun hingga sekarang, Anda hanya melihatnya sebagai bagian dari pernyataan penugasan. Dua parameter lainnya,JsonSerializerOptions
danCancellationToken
, bersifat opsional dan dihilangkan dalam cuplikan kode.Metode
DeserializeAsync
adalah generik, yang berarti Anda memberikan argumen jenis untuk jenis objek yang harus dibuat dari teks JSON. Dalam contoh ini, Anda melakukan deserializing keList<Repository>
, yang merupakan objek umum lainnya, a System.Collections.Generic.List<T>. KelasList<T>
menyimpan koleksi objek. Argumen jenis mendeklarasikan jenis objek yang disimpan diList<T>
. Argumen jenis adalah rekaman AndaRepository
, karena teks JSON mewakili kumpulan objek repositori.Tambahkan kode untuk menampilkan nama setiap repositori. Ganti baris yang berbunyi:
Console.Write(json);
dengan kode berikut:
foreach (var repo in repositories ?? Enumerable.Empty<Repository>()) Console.Write(repo.name);
Arahan berikut
using
harus ada di bagian atas file:using System.Net.Http.Headers; using System.Text.Json;
Menjalankan aplikasi.
dotnet run
Outputnya adalah daftar nama repositori yang merupakan bagian dari .NET Foundation.
Konfigurasi deserialisasi
Di Repository.cs, ganti konten file dengan C#berikut.
using System.Text.Json.Serialization; public record class Repository( [property: JsonPropertyName("name")] string Name);
Kode ini:
- Mengubah nama properti menjadi
name
Name
. - JsonPropertyNameAttribute Menambahkan untuk menentukan bagaimana properti ini muncul di JSON.
- Mengubah nama properti menjadi
Di Program.cs, perbarui kode untuk menggunakan kapitalisasi baru dari properti
Name
:foreach (var repo in repositories) Console.Write(repo.Name);
Menjalankan aplikasi.
Outputnya sama.
Refaktor kode
Metode ProcessRepositoriesAsync
dapat melakukan pekerjaan asinkron dan mengembalikan koleksi repositori. Ubah metode tersebut untuk mengembalikan Task<List<Repository>>
, dan pindahkan kode yang menulis ke konsol di dekat pemanggilnya.
Ubah tanda tangan
ProcessRepositoriesAsync
untuk mengembalikan tugas yang hasilnya berupa daftar objekRepository
:static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client)
Kembalikan repositori setelah memproses respons JSON:
await using Stream stream = await client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos"); var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(stream); return repositories ?? new();
Pengompilasi menghasilkan objek
Task<T>
untuk nilai kembalian karena Anda telah menandai metode ini sebagaiasync
.Ubah file Program.cs , ganti panggilan ke
ProcessRepositoriesAsync
dengan yang berikut ini untuk mengambil hasilnya dan menulis setiap nama repositori ke konsol.var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) Console.Write(repo.Name);
Menjalankan aplikasi.
Outputnya sama.
Deserialisasi lebih banyak properti
Langkah-langkah berikut menambahkan kode untuk memproses lebih banyak properti dalam paket JSON yang diterima. Anda mungkin tidak ingin memproses setiap properti, tetapi menambahkan beberapa properti lagi menunjukkan fitur lain dari C#.
Ganti konten
Repository
kelas, dengan definisi berikutrecord
:using System.Text.Json.Serialization; public record class Repository( [property: JsonPropertyName("name")] string Name, [property: JsonPropertyName("description")] string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, [property: JsonPropertyName("homepage")] Uri Homepage, [property: JsonPropertyName("watchers")] int Watchers);
Jenis Uri dan
int
memiliki fungsionalitas bawaan untuk mengonversi ke dan dari representasi string. Tidak ada kode tambahan yang diperlukan untuk mendeserialisasi dari format string JSON ke jenis target tersebut. Jika paket JSON berisi data yang tidak dikonversi ke jenis target, tindakan serialisasi akan melemparkan pengecualian.Perbarui perulangan
foreach
dalam file Program.cs untuk menampilkan nilai properti:foreach (var repo in repositories) { Console.WriteLine($"Name: {repo.Name}"); Console.WriteLine($"Homepage: {repo.Homepage}"); Console.WriteLine($"GitHub: {repo.GitHubHomeUrl}"); Console.WriteLine($"Description: {repo.Description}"); Console.WriteLine($"Watchers: {repo.Watchers:#,0}"); Console.WriteLine(); }
Menjalankan aplikasi.
Daftar sekarang termasuk properti tambahan.
Tambahkan properti tanggal
Tanggal operasi pendorongan terakhir diformat dengan cara ini dalam respons JSON:
2016-02-08T21:27:00Z
Format ini untuk Waktu Universal Terkoordinasi (UTC), sehingga hasil deserialisasi adalah nilai DateTime yang properti Kind-nya adalah Utc.
Untuk mendapatkan tanggal dan waktu yang diwakili di zona waktu Anda, Anda harus menulis metode konversi kustom.
Di Repository.cs, tambahkan properti untuk representasi UTC tanggal dan waktu dan properti baca-saja
LastPush
yang mengembalikan tanggal yang dikonversi ke waktu lokal, file akan terlihat seperti berikut ini:using System.Text.Json.Serialization; public record class Repository( [property: JsonPropertyName("name")] string Name, [property: JsonPropertyName("description")] string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, [property: JsonPropertyName("homepage")] Uri Homepage, [property: JsonPropertyName("watchers")] int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc) { public DateTime LastPush => LastPushUtc.ToLocalTime(); }
Properti
LastPush
didefinisikan menggunakan anggota bertubuh ekspresi untuk aksesorget
. Tidak ada pengaksesset
. Menghilangkan pengaksesset
adalah salah satu cara untuk menentukan properti baca-saja di C#. (Ya, Anda dapat membuat properti tulis-saja di C#, tetapi nilainya terbatas.)Tambahkan pernyataan output lain di Program.cs: lagi:
Console.WriteLine($"Last push: {repo.LastPush}");
Aplikasi lengkap harus menyerupai file Program.cs berikut:
using System.Net.Http.Headers; using System.Text.Json; using HttpClient client = new(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json")); client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter"); var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) { Console.WriteLine($"Name: {repo.Name}"); Console.WriteLine($"Homepage: {repo.Homepage}"); Console.WriteLine($"GitHub: {repo.GitHubHomeUrl}"); Console.WriteLine($"Description: {repo.Description}"); Console.WriteLine($"Watchers: {repo.Watchers:#,0}"); Console.WriteLine($"{repo.LastPush}"); Console.WriteLine(); } static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client) { await using Stream stream = await client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos"); var repositories = await JsonSerializer.DeserializeAsync<List<Repository>>(stream); return repositories ?? new(); }
Menjalankan aplikasi.
Outputnya mencakup tanggal dan waktu pendorongan terakhir ke setiap repositori.
Langkah berikutnya
Dalam tutorial ini, Anda membuat aplikasi yang membuat permintaan web dan mengurai hasilnya. Versi aplikasi Anda sekarang harus cocok dengan sampel yang sudah selesai.
Pelajari selengkapnya tentang cara mengonfigurasi serialisasi JSON di Cara membuat serialisasi dan deserialisasi (marshal dan unmarshal) JSON di .NET.