Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Tutorial ini membangun aplikasi yang mengeluarkan permintaan HTTP ke layanan REST di GitHub. Aplikasi ini membaca informasi dalam format JSON dan mengonversi JSON menjadi objek C#. Mengonversi dari objek JSON ke C# dikenal sebagai deserialisasi.
Tutorial menunjukkan cara:
- Kirim permintaan HTTP.
- Mendeserialisasi 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
Membuat aplikasi klien
Buka perintah dan buat direktori baru untuk aplikasi Anda. Jadikan itu direktori saat ini.
Masukkan perintah berikut di jendela konsol:
dotnet new console --name WebAPIClientPerintah ini membuat file awal untuk aplikasi "Hello World" dasar. Nama proyek adalah "WebAPIClient".
Navigasikan ke direktori "WebAPIClient", dan jalankan aplikasi.
cd WebAPIClientdotnet rundotnet runsecara otomatis dijalankandotnet restoreuntuk memulihkan apa pun dependensi yang dibutuhkan aplikasi. Ini juga menjalankandotnet buildjika diperlukan. Anda sebaiknya melihat output aplikasi"Hello, World!". Di terminal Anda, tekan Ctrl+C untuk menghentikan aplikasi.
Membuat permintaan HTTP
Aplikasi ini memanggil GITHub API untuk mendapatkan informasi tentang proyek di bawah payung .NET Foundation . Titik akhir adalah https://api.github.com/orgs/dotnet/repos. Untuk mengambil informasi, ini 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 pemrosesan.
HttpClient Gunakan kelas untuk membuat permintaan HTTP. HttpClient hanya mendukung metode asinkron untuk API yang berjalan lama. Jadi langkah-langkah berikut membuat metode asinkron dan memanggilnya dari metode Utama.
Program.csBuka 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.WriteLinedengan panggilan keProcessRepositoriesAsyncyang menggunakan kata kunciawait. - Mendefinisikan metode kosong
ProcessRepositoriesAsync.
- Mengganti pernyataan
Di kelas
Program, gunakan HttpClient untuk mengatasi permintaan dan respons, dengan mengganti konten dengan kode C# berikut ini.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
Acceptuntuk menerima respons JSON - Sebuah
User-Agentheader. 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 endpoint 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 tanggapan
jsondicetak pada konsol.
Buat aplikasi dan jalankan.
dotnet runTidak ada peringatan build karena sekarang terdapat operator
ProcessRepositoriesAsyncdi dalamawait. Keluaran merupakan tampilan panjang teks JSON.
Deserialisasi Hasil JSON
Langkah-langkah berikut menyederhanakan pendekatan untuk mengambil data dan memprosesnya. Anda akan menggunakan GetFromJsonAsync metode ekstensi yang menjadi bagian 📦 dari paket System.Net.Http.Json NuGet untuk mengambil dan mendeserialisasi hasil JSON ke dalam 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 API GitHub. Anda akan menggunakan kelas ini untuk menampilkan daftar nama repositori.
Properti JSON untuk objek repositori berisi puluhan properti, tetapi hanya properti
Nameyang akan dideserialisasi. Serializer secara otomatis mengabaikan properti JSON yang tidak ada kecocokan di kelas target. Fitur ini memudahkan untuk membuat jenis yang hanya berfungsi dengan subset bidang dalam paket JSON besar.Meskipun metode yang
GetFromJsonAsyncakan Anda gunakan di titik berikutnya memiliki manfaat tidak peka huruf besar/kecil dalam hal nama properti, konvensi C# adalah untuk memanfaatkan huruf pertama nama properti.HttpClientJsonExtensions.GetFromJsonAsync Gunakan metode untuk mengambil dan mengonversi JSON menjadi objek C#. Ganti panggilan ke GetStringAsync(String) dalam
ProcessRepositoriesAsyncmetode dengan baris berikut:var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos");Kode yang diperbarui menggantikan GetStringAsync(String) dengan HttpClientJsonExtensions.GetFromJsonAsync.
Argumen pertama ke
GetFromJsonAsyncmetode adalahawaitekspresi.awaitekspresi dapat muncul hampir di mana saja dalam kode Anda, meskipun hingga sekarang, Anda hanya melihatnya sebagai bagian dari pernyataan penugasan. Parameter berikutnya,requestUribersifat opsional dan tidak harus disediakan jika sudah ditentukan saat membuatclientobjek. Anda tidak menyediakanclientobjek dengan URI untuk mengirim permintaan, jadi Anda menentukan URI sekarang. Parameter opsional terakhir, dihilangkanCancellationTokendalam cuplikan kode.Metode
GetFromJsonAsyncini umum, yang berarti Anda menyediakan argumen jenis untuk jenis objek apa yang harus dibuat dari teks JSON yang diambil. Dalam contoh ini, Anda mendeserialisasi keList<Repository>, yang merupakan objek generik lainnya, yaitu System.Collections.Generic.List<T>. KelasList<T>menyimpan kumpulan objek. Argumen jenis mendeklarasikan jenis objek yang disimpan dalamList<T>. Argumen tipe adalah catatan 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.WriteLine(repo.Name);Direktif berikut
usingharus ada di bagian atas file:using System.Net.Http.Headers; using System.Net.Http.Json;Jalankan aplikasi.
dotnet runOutput adalah daftar nama repositori yang merupakan bagian dari .NET Foundation.
Refaktorisasi kode
Metode ini 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
ProcessRepositoriesAsyncuntuk mengembalikan tugas yang hasilnya adalah daftarRepositoryobjek:static async Task<List<Repository>> ProcessRepositoriesAsync(HttpClient client)Kembalikan repositori setelah memproses respons JSON:
var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos"); return repositories ?? new();Pengkompilasi menghasilkan
Task<T>objek untuk nilai pengembalian karena Anda telah menandai metode ini sebagaiasync.Ubah file Program.cs, mengganti panggilan ke
ProcessRepositoriesAsyncdengan yang berikut untuk mengambil hasil dan menulis setiap nama repositori ke konsol.var repositories = await ProcessRepositoriesAsync(client); foreach (var repo in repositories) Console.WriteLine(repo.Name);Jalankan aplikasi.
Outputnya sama.
Deserialisasi lebih banyak properti
Dalam langkah-langkah berikut, kami memperluas kode untuk memproses lebih banyak properti dari payload JSON yang dikembalikan oleh API GitHub. Anda mungkin tidak perlu memproses setiap properti, tetapi menambahkan beberapa menunjukkan fitur C# tambahan.
Ganti konten
Repositorykelas dengan definisi berikutrecord. Pastikan untuk mengimporSystem.Text.Json.Serializationnamespace dan menerapkan atribut[JsonPropertyName]untuk secara eksplisit memetakan bidang JSON ke properti C#.using System.Text.Json.Serialization; public record class Repository( string Name, string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, Uri Homepage, int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc );Jenis Uri dan
intmemiliki 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.JSON sering menggunakan
lowercaseatausnake_caseuntuk nama properti. Bidang sepertihtml_urldanpushed_attidak mengikuti konvensi penamaan C# PascalCase. Menggunakan[JsonPropertyName]memastikan bahwa kunci JSON ini terikat dengan benar ke properti C# yang sesuai, bahkan ketika namanya berbeda jika atau berisi garis bawah. Pendekatan ini menjamin deserialisasi yang dapat diprediksi dan stabil sambil memungkinkan nama properti PascalCase dalam C#. Selain itu, metodeGetFromJsonAsyncini digunakancase-insensitiveketika mencocokkan nama properti, jadi tidak ada konversi lebih lanjut yang diperlukan.Perbarui perulangan
foreachdalam 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(); }Jalankan aplikasi.
Daftar ini sekarang menyertakan properti tambahan.
Menambahkan 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 DateTime nilai yang propertinya Kind adalah Utc.
Untuk mendapatkan tanggal dan waktu yang diwakili di zona waktu, Anda harus menulis metode konversi kustom.
Di Repository.cs, tambahkan properti untuk representasi UTC dari tanggal dan waktu dan properti readonly
LastPushyang mengembalikan tanggal yang dikonversi ke waktu lokal, file akan terlihat seperti berikut ini:using System.Text.Json.Serialization; public record class Repository( string Name, string Description, [property: JsonPropertyName("html_url")] Uri GitHubHomeUrl, Uri Homepage, int Watchers, [property: JsonPropertyName("pushed_at")] DateTime LastPushUtc ) { public DateTime LastPush => LastPushUtc.ToLocalTime(); }Properti
LastPushdidefinisikan menggunakan anggota berwujud ekspresi untukgetaksesor. Tidak adasetaksesor. Menghilangkansetaksesor 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: sekali lagi:
Console.WriteLine($"Last push: {repo.LastPush}");Aplikasi lengkap harus menyerupai file Program.cs berikut:
using System.Net.Http.Headers; using System.Net.Http.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) { var repositories = await client.GetFromJsonAsync<List<Repository>>("https://api.github.com/orgs/dotnet/repos"); return repositories ?? new List<Repository>(); }Jalankan aplikasi.
Output mencakup tanggal dan waktu pengunggahan 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 lebih lanjut tentang mengonfigurasi serialisasi JSON di Cara melakukan serialisasi dan deserialisasi (marshal dan unmarshal) JSON di .NET.