Jika Anda membutuhkan jawaban singkat dan teknis, langsung ke bagian terakhir dari jawabannya.
Jika Anda ingin tahu lebih baik, baca semuanya, dan saya harap Anda akan menikmati ...
Saya membalas masalah ini juga hari ini, dan yang saya temukan hari ini adalah:
jawaban di atas benar, seperti:
1.1 ia memberi tahu Anda bahwa tajuk yang Anda coba tambahkan sudah ada dan Anda kemudian harus memodifikasi nilainya menggunakan properti yang sesuai (pengindeks, misalnya), alih-alih mencoba menambahkannya lagi.
1.2 Kapan pun Anda mengubah tajuk HttpWebRequest
, Anda harus menggunakan properti yang sesuai pada objek itu sendiri, jika ada.
Terima kasih untuk dan Jvenema untuk pedoman terkemuka ...
Tapi, apa yang saya temukan, dan itu adalah bagian yang hilang dalam teka-teki itu adalah:
2.1 WebHeaderCollection
Kelas umumnya diakses melalui. WebRequest
Pemimpin atau WebResponse
. Pemimpin. Beberapa tajuk umum dianggap dibatasi dan terpapar langsung oleh API (seperti Jenis Konten) atau dilindungi oleh sistem dan tidak dapat diubah.
Header yang dibatasi adalah:
Accept
Connection
Content-Length
Content-Type
Date
Expect
Host
If-Modified-Since
Range
Referer
Transfer-Encoding
User-Agent
Proxy-Connection
Jadi, lain kali Anda menghadapi pengecualian ini dan tidak tahu bagaimana menyelesaikannya, ingatlah bahwa ada beberapa header terbatas, dan solusinya adalah mengubah nilai-nilai mereka menggunakan properti yang sesuai secara eksplisit dari kelas WebRequest
/ HttpWebRequest
.
Edit: (berguna, dari komentar, komentar oleh pengguna Kaido )
Solusi adalah untuk memeriksa apakah header sudah ada atau dibatasi ( WebHeaderCollection.IsRestricted(key)
) sebelum memanggil add
Headers.Add()
sudah ada karena itu kita harus memodifikasinya.Saya mengalami masalah ini dengan klien web kustom. Saya pikir orang mungkin menjadi bingung karena beberapa cara untuk melakukan ini. Saat menggunakan,
WebRequest.Create()
Anda dapat melakukan cast keHttpWebRequest
dan menggunakan properti untuk menambah atau memodifikasi header. Saat menggunakan,WebHeaderCollection
Anda dapat menggunakan.Add("referer","my_url")
.Kel 1
Kel 2
sumber
Semua jawaban sebelumnya menggambarkan masalah tanpa memberikan solusi. Berikut adalah metode ekstensi yang memecahkan masalah dengan memungkinkan Anda untuk mengatur header apa pun melalui nama string-nya.
Pemakaian
Kelas Ekstensi
Skenario
Saya menulis pembungkus untuk
HttpWebRequest
dan tidak ingin mengekspos ke-13 header terbatas sebagai properti di bungkus saya. Sebaliknya saya ingin menggunakan yang sederhanaDictionary<string, string>
.Contoh lain adalah proksi HTTP di mana Anda perlu mengambil tajuk dalam permintaan dan meneruskannya ke penerima.
Ada banyak skenario lain di mana tidak praktis atau mungkin untuk menggunakan properti. Memaksa pengguna untuk mengatur header melalui properti adalah desain yang sangat tidak fleksibel, oleh karena itu diperlukan refleksi. Sisi baiknya adalah refleksi itu disarikan, masih cepat (0,001 detik dalam tes saya), dan sebagai metode ekstensi terasa alami.
Catatan
Nama tajuk tidak sensitif huruf per RFC, http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
sumber
static Dictionary<string, PropertyInfo> HeaderProperties = new Dictionary<string, PropertyInfo>(StringComparer.InvariantCultureIgnoreCase); static WebRequestExtensions() { // Get property info for restricted headers. Type type = typeof(HttpWebRequest); foreach (string header in Enum.GetNames(typeof(HttpRequestHeader))) { var property = type.GetProperty(header.ToString()); if (property != null) { HeaderProperties.Add(property.Name, property); } } }
Saya memiliki pengecualian yang sama ketika kode saya mencoba mengatur nilai tajuk "Terima" seperti ini:
Solusinya adalah mengubahnya menjadi ini:
sumber
Setiap kali Anda mengubah tajuk
HttpWebRequest
, Anda harus menggunakan properti yang sesuai pada objek itu sendiri, jika ada. Jika Anda memiliki dataranWebRequest
, pastikan untuk melemparkannyaHttpWebRequest
terlebih dahulu. KemudianReferrer
dalam kasus Anda dapat diakses melalui((HttpWebRequest)request).Referrer
, sehingga Anda tidak perlu memodifikasi header secara langsung - cukup atur properti ke nilai yang tepat.ContentLength
,ContentType
,UserAgent
, Dll, semua perlu diatur dengan cara ini.IMHO, ini adalah kelemahan pada bagian MS ... mengatur header melalui
Headers.Add()
harus secara otomatis memanggil properti yang sesuai di belakang layar, jika itu yang ingin mereka lakukan.sumber
WebRequest bersifat abstrak (dan karena setiap kelas warisan harus menimpa properti Header) .. WebRequest konkret apa yang Anda gunakan? Dengan kata lain, bagaimana Anda mendapatkan objek WebRequest yang akan ditandatangani?
ehr .. jawaban saya membuat saya menyadari bahwa pesan kesalahan yang Anda peroleh sebenarnya tepat: ia memberi tahu Anda bahwa tajuk yang Anda coba tambahkan sudah ada dan kemudian Anda harus mengubah nilainya menggunakan properti yang sesuai (pengindeks, misalnya, ), alih-alih mencoba menambahkannya lagi. Mungkin itu yang Anda cari.
Kelas lain yang mewarisi dari WebRequest mungkin memiliki properti yang lebih baik yang membungkus header tertentu; Lihat posting ini misalnya.
sumber
Jawaban di atas semuanya baik-baik saja, tetapi inti dari masalah ini adalah bahwa beberapa tajuk diatur satu arah, dan yang lain diatur dengan cara lain. Lihat di atas untuk daftar 'header terbatas'. Untuk ini, Anda cukup menetapkannya sebagai properti. Untuk yang lain, Anda sebenarnya menambahkan tajuk. Lihat disini.
sumber
Pada dasarnya tidak. Itu adalah tajuk http, jadi masuk akal untuk menggunakan
HttpWebRequest
dan menyetel.Referer
(seperti yang Anda tunjukkan dalam pertanyaan):sumber
Catatan: solusi ini akan bekerja dengan WebClientSocket serta dengan HttpWebRequest atau kelas lain yang menggunakan WebHeaderCollection untuk bekerja dengan header.
Jika Anda melihat kode sumber WebHeaderCollection.cs Anda akan melihat bahwa Hinfo digunakan untuk menyimpan informasi dari semua header yang dikenal:
Melihat kelas HeaderInfoTable, Anda dapat melihat semua data disimpan ke dalam tabel hash
Selanjutnya, dalam kontruktor statis HeaderInfoTable, Anda dapat melihat semua header yang dikenal ditambahkan dalam array HeaderInfo dan kemudian disalin ke dalam hashtable.
Tampilan akhir di kelas HeaderInfo menunjukkan nama bidang.
Jadi, dengan semua hal di atas, berikut adalah kode yang menggunakan refleksi untuk menemukan Hashtable statis di kelas HeaderInfoTable dan kemudian mengubah setiap HeaderInfo permintaan-dibatasi di dalam tabel hash menjadi tidak dibatasi
sumber
Saya hanya menggunakan:
sumber
Anda bisa mengirimkan WebRequest ke HttpWebRequest yang ditunjukkan di bawah ini:
dan kemudian alih-alih mencoba memanipulasi daftar tajuk, menerapkannya langsung di permintaan properti permintaan.
Properti ini tersedia di objek permintaan.
sumber