Jika saya ingin mengirimkan permintaan dapatkan http menggunakan System.Net.HttpClient tampaknya tidak ada api untuk menambahkan parameter, apakah ini benar?
Apakah ada api sederhana yang tersedia untuk membangun string kueri yang tidak melibatkan pembuatan koleksi nilai nama dan url yang mengkodekannya dan akhirnya menggabungkannya? Saya berharap untuk menggunakan sesuatu seperti api RestSharp (yaitu AddParameter (..))
Jawaban:
Iya.
Tentu:
akan memberi Anda hasil yang diharapkan:
Anda mungkin juga menemukan
UriBuilder
kelas yang berguna:akan memberi Anda hasil yang diharapkan:
Anda bisa memberi makan lebih aman ke
HttpClient.GetAsync
metode Anda .sumber
#
) untuk Anda menggunakan properti Fragmen. Saya telah melihat begitu banyak orang melakukan kesalahan dalam menangani url secara manual alih-alih menggunakan alat bawaan.NameValueCollection.ToString()
biasanya tidak membuat string kueri, dan tidak ada dokumentasi yang menyatakan bahwa melakukanToString
pada hasilParseQueryString
akan menghasilkan string kueri baru, sehingga bisa pecah kapan saja karena tidak ada jaminan dalam fungsionalitas itu.Bagi mereka yang tidak ingin memasukkan
System.Web
dalam proyek yang belum menggunakannya, Anda dapat menggunakanFormUrlEncodedContent
dariSystem.Net.Http
dan melakukan sesuatu seperti berikut:versi kunciperbaikan kunci
versi kamus
sumber
dispose
? Saya selalu membuang kecuali saya memiliki alasan yang baik untuk tidak melakukannya, seperti menggunakan kembaliHttpClient
.TL; DR: jangan gunakan versi yang diterima karena itu benar-benar rusak dalam kaitannya dengan penanganan karakter unicode, dan tidak pernah menggunakan API internal
Saya benar-benar menemukan masalah penyandian ganda yang aneh dengan solusi yang diterima:
Jadi, Jika Anda berurusan dengan karakter yang perlu disandikan, solusi yang diterima mengarah ke penyandian ganda:
NameValueCollection
pengindeks ( dan ini menggunakanUrlEncodeUnicode
, tidak diharapkan biasaUrlEncode
(!) )uriBuilder.Uri
membuatUri
konstruktor menggunakan baru yang melakukan pengkodean sekali lagi (pengodean url normal)uriBuilder.ToString()
(meskipun ini mengembalikan benarUri
IMO mana yang setidaknya tidak konsisten, mungkin bug, tapi itu pertanyaan lain) dan kemudian menggunakanHttpClient
metode menerima string - klien masih membuatUri
keluar dari string yang Anda kirimkan seperti ini:new Uri(uri, UriKind.RelativeOrAbsolute)
Repro kecil, tetapi penuh:
Keluaran:
Seperti yang Anda lihat, tidak masalah jika Anda melakukan
uribuilder.ToString()
+httpClient.GetStringAsync(string)
atauuriBuilder.Uri
+httpClient.GetStringAsync(Uri)
Anda akhirnya mengirim parameter ganda yang dikodekanContoh tetap dapat:
Tapi ini menggunakan konstruktor usang
Uri
PS pada .NET terbaru saya di Windows Server,
Uri
konstruktor dengan komentar bool doc mengatakan "usang, dontEscape selalu salah", tetapi sebenarnya berfungsi seperti yang diharapkan (melompat keluar)Jadi sepertinya ada bug lain ...
Dan bahkan ini jelas salah - ia mengirim UrlEncodedUnicode ke server, bukan hanya UrlEncoded yang diharapkan server
Pembaruan: satu hal lagi adalah, NameValueCollection sebenarnya melakukan UrlEncodeUnicode, yang tidak seharusnya digunakan lagi dan tidak kompatibel dengan url.encode / decode biasa (lihat NameValueCollection to URL Query? ).
Jadi intinya adalah: jangan pernah menggunakan hack ini
NameValueCollection query = HttpUtility.ParseQueryString(builder.Query);
karena akan mengacaukan parameter permintaan unicode Anda. Cukup buat query secara manual dan tetapkan keUriBuilder.Query
yang akan melakukan pengkodean yang diperlukan dan kemudian gunakan UriUriBuilder.Uri
.Contoh utama menyakiti diri sendiri dengan menggunakan kode yang tidak seharusnya digunakan seperti ini
sumber
var namedValues = HttpUtility.ParseQueryString(builder.Query)
, tetapi alih-alih menggunakan NameValueCollection yang dikembalikan, segera konversikan ke Kamus seperti:var dic = values.ToDictionary(x => x, x => values[x]);
Tambahkan nilai baru ke kamus, lalu meneruskannya ke konstruktorFormUrlEncodedContent
dan panggilReadAsStringAsync().Result
. Itu memberi Anda string kueri yang disandikan dengan benar, yang dapat Anda tetapkan kembali ke UriBuilder.<add key="aspnet:DontUsePercentUUrlEncoding" value="true" />
. Saya tidak akan bergantung pada perilaku ini, jadi lebih baik menggunakan kelas FormUrlEncodedContent, seperti yang ditunjukkan oleh jawaban sebelumnya: stackoverflow.com/a/26744471/88409Dalam proyek ASP.NET Core Anda bisa menggunakan kelas QueryHelpers.
sumber
Anda mungkin ingin memeriksa Flurl [pengungkapan: Saya penulisnya], pembuat URL yang lancar dengan lib pengiring opsional yang memperluasnya menjadi klien REST yang lengkap.
Lihat dokumen untuk detail lebih lanjut. Paket lengkap tersedia di NuGet:
PM> Install-Package Flurl.Http
atau hanya pembuat URL yang berdiri sendiri:
PM> Install-Package Flurl
sumber
Uri
atau mulai dengan kelas Anda sendiristring
?Url
kelas saya sendiri . Di atas setara dengannew Url("https://api.com").AppendPathSegment...
Secara Pribadi saya lebih suka ekstensi string karena penekanan tombol lebih sedikit dan standar pada mereka dalam dokumen, tetapi Anda bisa melakukannya dengan cara baik.Sepanjang baris yang sama dengan posting Rostov, jika Anda tidak ingin memasukkan referensi ke
System.Web
dalam proyek Anda, Anda dapat menggunakanFormDataCollection
dariSystem.Net.Http.Formatting
dan melakukan sesuatu seperti berikut:Menggunakan
System.Net.Http.Formatting.FormDataCollection
sumber
Darin menawarkan solusi yang menarik dan cerdas, dan ini adalah sesuatu yang mungkin menjadi pilihan lain:
dan saat menggunakannya, Anda dapat melakukan ini:
sumber
kvp.Key
dankvp.Value
secara terpisah di dalam for loop, bukan dalam string-kueri penuh (sehingga tidak encoding&
, dan=
karakter).server.UrlEncode
dapat diganti denganWebUtility.UrlEncode
Atau cukup menggunakan ekstensi Uri saya
Kode
Pemakaian
Hasil
sumber
The RFC 6570 URI Template perpustakaan Aku sedang mengembangkan mampu melakukan operasi ini. Semua pengodean ditangani untuk Anda sesuai dengan RFC itu. Pada saat penulisan ini, rilis beta tersedia dan satu-satunya alasan itu tidak dianggap rilis stabil 1.0 adalah dokumentasi tidak sepenuhnya memenuhi harapan saya (lihat masalah # 17 , # 18 , # 32 , # 43 ).
Anda bisa membuat string kueri sendirian:
Atau Anda dapat membangun URI lengkap:
sumber
Karena saya harus menggunakan kembali beberapa waktu ini, saya datang dengan kelas ini yang hanya membantu mengabstraksi bagaimana string kueri disusun.
Penggunaannya akan disederhanakan menjadi seperti ini:
yang akan mengembalikan uri: http://example.com/?foo=bar%3c%3e%26-baz&bar=second
sumber
Untuk menghindari masalah pengodean ganda yang dijelaskan dalam jawaban taras.roshko dan untuk menjaga kemungkinan agar mudah bekerja dengan parameter kueri, Anda bisa menggunakan
uriBuilder.Uri.ParseQueryString()
alih-alihHttpUtility.ParseQueryString()
.sumber
Sebagian baik dari jawaban yang diterima, dimodifikasi untuk menggunakan UriBuilder.Uri.ParseQueryString () alih-alih HttpUtility.ParseQueryString ():
sumber
ParseQueryString()
metode ekstensi tidak adaSystem
.Berkat "Darin Dimitrov", Ini adalah metode ekstensi.
sumber
Saya tidak dapat menemukan solusi yang lebih baik daripada membuat metode ekstensi untuk mengonversi Kamus ke QueryStringFormat. Solusi yang diajukan oleh Waleed AK juga bagus.
Ikuti solusi saya:
Buat metode ekstensi:
Dan mereka:
sumber