Tugas umum saat memanggil sumber daya web dari kode adalah membangun string kueri untuk memasukkan semua parameter yang diperlukan. Meskipun tidak berarti ilmu roket, ada beberapa detail bagus yang perlu Anda perhatikan, menambahkan &
parameter if not first, encoding the etc.
Kode untuk melakukannya sangat sederhana, tetapi sedikit membosankan:
StringBuilder SB = new StringBuilder();
if (NeedsToAddParameter A)
{
SB.Append("A="); SB.Append(HttpUtility.UrlEncode("TheValueOfA"));
}
if (NeedsToAddParameter B)
{
if (SB.Length>0) SB.Append("&");
SB.Append("B="); SB.Append(HttpUtility.UrlEncode("TheValueOfB")); }
}
Ini adalah tugas umum yang diharapkan ada kelas utilitas yang membuatnya lebih elegan dan mudah dibaca. Memindai MSDN, saya gagal menemukannya — yang membawa saya ke pertanyaan berikut:
Apa cara bersih paling elegan yang Anda tahu melakukan hal di atas?
c#
.net
url
query-string
Boas
sumber
sumber
Jawaban:
Jika Anda melihat di bawah kap properti QueryString adalah NameValueCollection. Ketika saya telah melakukan hal-hal serupa, saya biasanya tertarik pada serialisasi DAN deserialising sehingga saran saya adalah untuk membangun NameValueCollection dan kemudian meneruskan ke:
Saya membayangkan ada cara super elegan untuk melakukan ini di LINQ juga ...
sumber
application/x-www-form-urlencoded
, dan sebenarnya ditentukan oleh HTML, untuk tujuan mengirimkan data formulir sebagai bagian dariGET
permintaan. HTML 5 tidak melarang beberapa nilai per kunci dalam format ini, dan pada kenyataannya itu mensyaratkan bahwa browser menghasilkan beberapa nilai per kunci dalam kasus bahwa halaman (salah) berisi beberapa bidang denganname
atribut yang sama . Lihat goo.gl/uk1AgAnda dapat membuat instance baru yang dapat ditulisi
HttpValueCollection
dengan meneleponSystem.Web.HttpUtility.ParseQueryString(string.Empty)
, dan kemudian menggunakannya seperti apa punNameValueCollection
. Setelah menambahkan nilai yang Anda inginkan, Anda dapat memanggilToString
koleksi untuk mendapatkan string kueri, sebagai berikut:Ini
HttpValueCollection
internal dan jadi Anda tidak bisa langsung membuat instance. Namun, begitu Anda mendapatkan sebuah instance, Anda dapat menggunakannya seperti yang lainnyaNameValueCollection
. Karena objek aktual yang Anda gunakan adalahHttpValueCollection
, memanggil metode ToString akan memanggil metode yang digantiHttpValueCollection
, yang memformat koleksi sebagai string kueri yang disandikan URL.Setelah mencari SO dan web untuk mencari jawaban atas masalah serupa, ini adalah solusi paling sederhana yang bisa saya temukan.
.NET Core
Jika Anda bekerja di .NET Core, Anda bisa menggunakan
Microsoft.AspNetCore.WebUtilities.QueryHelpers
kelas, yang sangat menyederhanakan ini.https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.webutilities.queryhelpers
Kode sampel:
sumber
public static string ToURLQueryString(this IDictionary dict) { ... }
Add
metode ini. YaituqueryString.Add("type", "1"); queryString.Add("type", "2");
MenggunakanAdd
metode ini mungkin cara yang lebih baik untuk melakukan ini sepanjang waktu sebenarnya.Dengan inspirasi dari komentar Roy Tinker, saya akhirnya menggunakan metode ekstensi sederhana pada kelas Uri yang membuat kode saya ringkas dan bersih:
Pemakaian:
Edit - Varian yang memenuhi standar
Seperti yang ditunjukkan beberapa orang,
httpValueCollection.ToString()
menyandikan karakter Unicode dengan cara yang tidak sesuai standar . Ini adalah varian dari metode ekstensi yang sama yang menangani karakter seperti itu dengan menggunakanHttpUtility.UrlEncode
metode alih-alih metode yang sudah tidakHttpUtility.UrlEncodeUnicode
digunakan lagi .sumber
Saya menjawab pertanyaan serupa beberapa waktu lalu. Pada dasarnya, cara terbaik adalah menggunakan kelas
HttpValueCollection
, yaitu ASP.NETRequest.QueryString
properti sebenarnya, sayangnya itu internal dalam kerangka NET. Anda bisa menggunakan Reflector untuk mengambilnya (dan letakkan di kelas Utils Anda). Dengan cara ini Anda bisa memanipulasi string kueri seperti NameValueCollection, tetapi dengan semua masalah penyandian / penguraian url Anda.HttpValueCollection
meluasNameValueCollection
, dan memiliki konstruktor yang mengambil string kueri yang disandikan (termasuk ampersand dan tanda tanya), dan menimpaToString()
metode untuk nanti membangun kembali string kueri dari koleksi yang mendasarinya.Contoh:
sumber
httpValueCollection.ToString()
sebenarnya panggilanhttpValueCollection.ToString(true)
sehingga menambahkantrue
kejelasan tidak diperlukan.Inilah cara fasih / lambda-ish sebagai metode ekstensi (menggabungkan konsep di posting sebelumnya) yang mendukung banyak nilai untuk kunci yang sama. Preferensi pribadi saya adalah ekstensi daripada pembungkus untuk kemampuan menemukan oleh anggota tim lainnya untuk hal-hal seperti ini. Perhatikan bahwa ada kontroversi seputar metode pengkodean, banyak posting tentang hal itu di Stack Overflow (satu posting seperti itu ) dan blogger MSDN (seperti yang ini ).
sunting: dengan dukungan nol, meskipun Anda mungkin perlu menyesuaikannya untuk situasi khusus Anda
sumber
Flurl [pengungkapan: Saya penulis] mendukung pembuatan string permintaan melalui objek anonim (antara lain):
Lib pendamping Flurl.Http opsional memungkinkan Anda untuk melakukan panggilan HTTP langsung dari rantai panggilan yang fasih yang sama, memperluasnya menjadi klien REST full-blown:
Paket lengkap tersedia di NuGet:
PM> Install-Package Flurl.Http
atau hanya pembuat URL yang berdiri sendiri:
PM> Install-Package Flurl
sumber
Inilah entri saya yang terlambat. Saya tidak suka yang lain karena berbagai alasan, jadi saya menulis sendiri.
Versi ini menampilkan:
Penggunaan StringBuilder saja. Tidak ada panggilan ToArray () atau metode ekstensi lainnya. Itu tidak terlihat secantik beberapa tanggapan lainnya, tetapi saya menganggap ini sebagai fungsi inti sehingga efisiensi lebih penting daripada memiliki kode "fasih", "satu garis" yang menyembunyikan ketidakefisienan.
Menangani beberapa nilai per kunci. (Tidak membutuhkannya sendiri tetapi hanya untuk membungkam Mauricio;)
Contoh Penggunaan
Keluaran
sumber
Bagaimana dengan membuat metode ekstensi yang memungkinkan Anda untuk menambahkan parameter dengan gaya fasih seperti ini?
Inilah kelebihan yang menggunakan
string
:Dan inilah kelebihan yang menggunakan
StringBuilder
:sumber
NameValueCollection
,HttpValueCollection
, atauUri
pertama. Terima kasih!Saya perlu memecahkan masalah yang sama untuk perpustakaan kelas portabel (PCL) yang saya kerjakan. Dalam hal ini, saya tidak memiliki akses ke System.Web jadi saya tidak bisa menggunakan ParseQueryString.
Sebaliknya saya menggunakan
System.Net.Http.FormUrlEncodedContent
seperti ini:sumber
sumber
.ToArray()
s.Tambahkan kelas ini ke proyek Anda
Dan gunakan seperti ini:
sumber
Penawaran saya:
Pemakaian:
sumber
Belum diuji, tapi saya pikir sesuatu di sepanjang garis ini akan bekerja dengan sangat baik
sumber
Versi berbasis metode ekstensi cepat:
Anda bisa menggunakan klausa where untuk memilih parameter mana yang ditambahkan ke string.
sumber
Dengan asumsi bahwa Anda ingin mengurangi dependensi ke majelis lain dan untuk menjaga hal-hal sederhana, Anda dapat melakukannya:
Ini bekerja dengan baik dengan loop juga. Penghapusan ampersand terakhir harus keluar dari loop.
Perhatikan bahwa operator concatenation digunakan untuk meningkatkan keterbacaan. Biaya menggunakannya dibandingkan dengan biaya menggunakan StringBuilder sangat minim (saya pikir Jeff Atwood memposting sesuatu pada topik ini).
sumber
Menggabungkan jawaban teratas untuk membuat versi objek anonim :
Itu menghasilkan ini:
Berikut kodenya:
sumber
Sama seperti solusi yang diterima, tetapi ditransfusikan ke sintaks "dot" LINQ ...
sumber
Saya punya metode ekstensi untuk Uri yang:
uri.WithQuery(new { name = "value" })
string/string
pasangan (mis. Kamus`2 ).string/object
pasangan (mis. RouteValueDictionary ).Versi yang didokumentasikan dapat ditemukan di sini .
Ekstensi:
Parser kueri:
Inilah tes-tesnya:
sumber
Kelas pembungkus rantai untuk HttpValueCollection:
Contoh penggunaan:
sumber
Saya menambahkan metode berikut ke kelas PageBase saya.
Memanggil:
sumber
Saya menulis beberapa metode ekstensi yang saya temukan sangat berguna ketika bekerja dengan QueryStrings. Seringkali saya ingin memulai dengan QueryString saat ini dan memodifikasi sebelum menggunakannya. Sesuatu seperti,
Untuk lebih banyak dan sumbernya: http://www.charlesrcook.com/archive/2008/07/23/c-extension-methods-for-asp.net-query-string-operations.aspx
Ini dasar, tapi saya suka gayanya.
sumber
Hanya ingin membuang 2 sen saya:
Dokumen mengatakan bahwa
uri.Query
akan dimulai dengan?
jika tidak kosong dan Anda harus memotongnya jika Anda akan memodifikasinya.Catatan yang
HttpUtility.UrlEncode
ditemukan diSystem.Web
.Pemakaian:
sumber
Meskipun tidak elegan, saya memilih versi yang lebih sederhana yang tidak menggunakan
NameValueCollecitons
- hanya pola pembangun melilitStringBuilder
.Per jawaban yang ada, saya memastikan untuk menggunakan
HttpUtility.UrlEncode
panggilan. Ini digunakan seperti:sumber
Keluaran:
Kode; Anda semua bisa berterima kasih kepada saya di suatu tempat, entah bagaimana: D
sumber
Saya pergi dengan solusi yang diusulkan oleh DSO (dijawab pada 2 Agustus '11 di 7:29), solusinya tidak memerlukan menggunakan HttpUtility. Namun, sesuai dengan artikel yang diposting di Dotnetpearls , menggunakan Kamus lebih cepat (dalam kinerja) daripada menggunakan NameValueCollection. Berikut ini adalah solusi DSO yang dimodifikasi untuk menggunakan Kamus sebagai pengganti NameValueCollection.
sumber
String kueri dapat ditambahkan ke URL dengan:
https://blog.codingnovice.com/blog
sumber
Saya menulis pembantu untuk proyek pisau cukur saya menggunakan beberapa petunjuk dari jawaban lain.
Bisnis ParseQueryString diperlukan karena kami tidak diizinkan untuk mengutak-atik objek QueryString dari permintaan saat ini.
Saya menggunakannya seperti ini:
Jika Anda ingin mengambil lebih dari satu nilai, cukup ubah parameter ke Kamus dan tambahkan pasangan ke string kueri.
sumber
Kode di bawah ini diambil dari
HttpValueCollection
implementasiToString
, melalui ILSpy, yang memberi Anda nama = nilai querystring.Sayangnya HttpValueCollection adalah kelas internal yang hanya akan Anda dapatkan kembali jika Anda gunakan
HttpUtility.ParseQueryString()
. Saya menghapus semua bagian kondisi tampilan untuk itu, dan menyandikan secara default:sumber
Ini identik dengan jawaban yang diterima kecuali sedikit lebih padat:
sumber
Hanya untuk mereka yang membutuhkan jawaban atas versi VB.NET:
Dan versi tanpa LINQ:
Dan versi C # tanpa LINQ:
sumber