Saya menggunakan WebClient
kelas untuk mengirim beberapa data ke formulir web. Saya ingin mendapatkan kode status tanggapan dari pengiriman formulir. Sejauh ini saya telah menemukan cara mendapatkan kode status jika ada pengecualian
Catch wex As WebException
If TypeOf wex.Response Is HttpWebResponse Then
msgbox(DirectCast(wex.Response, HttpWebResponse).StatusCode)
End If
Namun jika formulir berhasil dikirim dan tidak ada pengecualian yang dibuang maka saya tidak akan tahu kode statusnya (200.301.302, ...)
Apakah ada cara untuk mendapatkan kode status ketika tidak ada pengecualian?
NB: Saya memilih untuk tidak menggunakan httpwebrequest / httpwebresponse
Anda dapat memeriksa apakah kesalahan tersebut bertipe
WebException
dan kemudian memeriksa kode respons;if (e.Error.GetType().Name == "WebException") { WebException we = (WebException)e.Error; HttpWebResponse response = (System.Net.HttpWebResponse)we.Response; if (response.StatusCode==HttpStatusCode.NotFound) System.Diagnostics.Debug.WriteLine("Not found!"); }
atau
try { // send request } catch (WebException e) { // check e.Status as above etc.. }
sumber
Ada cara untuk melakukannya dengan refleksi. Ia bekerja dengan .NET 4.0. Itu mengakses bidang pribadi dan mungkin tidak bekerja di versi .NET tanpa modifikasi.
Saya tidak tahu mengapa Microsoft tidak mengekspos bidang ini dengan properti.
private static int GetStatusCode(WebClient client, out string statusDescription) { FieldInfo responseField = client.GetType().GetField("m_WebResponse", BindingFlags.Instance | BindingFlags.NonPublic); if (responseField != null) { HttpWebResponse response = responseField.GetValue(client) as HttpWebResponse; if (response != null) { statusDescription = response.StatusDescription; return (int)response.StatusCode; } } statusDescription = null; return 0; }
sumber
Jika Anda menggunakan .Net 4.0 (atau kurang):
class BetterWebClient : WebClient { private WebRequest _Request = null; protected override WebRequest GetWebRequest(Uri address) { this._Request = base.GetWebRequest(address); if (this._Request is HttpWebRequest) { ((HttpWebRequest)this._Request).AllowAutoRedirect = false; } return this._Request; } public HttpStatusCode StatusCode() { HttpStatusCode result; if (this._Request == null) { throw (new InvalidOperationException("Unable to retrieve the status code, maybe you haven't made a request yet.")); } HttpWebResponse response = base.GetWebResponse(this._Request) as HttpWebResponse; if (response != null) { result = response.StatusCode; } else { throw (new InvalidOperationException("Unable to retrieve the status code, maybe you haven't made a request yet.")); } return result; } }
Jika Anda menggunakan .Net 4.5.X atau yang lebih baru, beralihlah ke HttpClient :
var response = await client.GetAsync("http://www.contoso.com/"); var statusCode = response.StatusCode;
sumber
Jawaban Erik tidak berfungsi di Windows Phone sebagaimana adanya. Yang berikut ini:
class WebClientEx : WebClient { private WebResponse m_Resp = null; protected override WebResponse GetWebResponse(WebRequest Req, IAsyncResult ar) { try { this.m_Resp = base.GetWebResponse(request); } catch (WebException ex) { if (this.m_Resp == null) this.m_Resp = ex.Response; } return this.m_Resp; } public HttpStatusCode StatusCode { get { if (m_Resp != null && m_Resp is HttpWebResponse) return (m_Resp as HttpWebResponse).StatusCode; else return HttpStatusCode.OK; } } }
Setidaknya itu terjadi saat menggunakan
OpenReadAsync
; untuk yang lainxxxAsync
metode , pengujian yang cermat akan sangat disarankan. Kerangka kerja memanggil GetWebResponse di suatu tempat di sepanjang jalur kode; yang perlu dilakukan hanyalah menangkap dan menyimpan objek respons ke dalam cache.Kode fallback adalah 200 dalam cuplikan ini karena kesalahan HTTP asli - 500, 404, dll - tetap dilaporkan sebagai pengecualian. Tujuan dari trik ini adalah untuk menangkap kode non-kesalahan, dalam kasus khusus saya 304 (Tidak diubah). Jadi fallback mengasumsikan bahwa jika kode status entah bagaimana tidak tersedia, setidaknya kode itu tidak salah.
sumber
Kamu harus menggunakan
if (e.Status == WebExceptionStatus.ProtocolError) { HttpWebResponse response = (HttpWebResponse)ex.Response; if (response.StatusCode == HttpStatusCode.NotFound) System.Diagnostics.Debug.WriteLine("Not found!"); }
sumber
However if the form is submitted successfully and no exception is thrown...
Inilah yang saya gunakan untuk memperluas fungsionalitas WebClient. StatusCode dan StatusDescription akan selalu berisi kode / deskripsi respons terbaru.
/// <summary> /// An expanded web client that allows certificate auth and /// the retrieval of status' for successful requests /// </summary> public class WebClientCert : WebClient { private X509Certificate2 _cert; public WebClientCert(X509Certificate2 cert) : base() { _cert = cert; } protected override WebRequest GetWebRequest(Uri address) { HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address); if (_cert != null) { request.ClientCertificates.Add(_cert); } return request; } protected override WebResponse GetWebResponse(WebRequest request) { WebResponse response = null; response = base.GetWebResponse(request); HttpWebResponse baseResponse = response as HttpWebResponse; StatusCode = baseResponse.StatusCode; StatusDescription = baseResponse.StatusDescription; return response; } /// <summary> /// The most recent response statusCode /// </summary> public HttpStatusCode StatusCode { get; set; } /// <summary> /// The most recent response statusDescription /// </summary> public string StatusDescription { get; set; } }
Dengan demikian Anda dapat melakukan posting dan mendapatkan hasilnya melalui:
byte[] response = null; using (WebClientCert client = new WebClientCert()) { response = client.UploadValues(postUri, PostFields); HttpStatusCode code = client.StatusCode; string description = client.StatusDescription; //Use this information }
sumber
Untuk berjaga-jaga jika orang lain membutuhkan versi F # dari peretasan yang dijelaskan di atas.
open System open System.IO open System.Net type WebClientEx() = inherit WebClient () [<DefaultValue>] val mutable m_Resp : WebResponse override x.GetWebResponse (req: WebRequest ) = x.m_Resp <- base.GetWebResponse(req) (req :?> HttpWebRequest).AllowAutoRedirect <- false; x.m_Resp override x.GetWebResponse (req: WebRequest , ar: IAsyncResult ) = x.m_Resp <- base.GetWebResponse(req, ar) (req :?> HttpWebRequest).AllowAutoRedirect <- false; x.m_Resp member x.StatusCode with get() : HttpStatusCode = if not (obj.ReferenceEquals (x.m_Resp, null)) && x.m_Resp.GetType() = typeof<HttpWebResponse> then (x.m_Resp :?> HttpWebResponse).StatusCode else HttpStatusCode.OK let wc = new WebClientEx() let st = wc.OpenRead("http://www.stackoverflow.com") let sr = new StreamReader(st) let res = sr.ReadToEnd() wc.StatusCode sr.Close() st.Close()
sumber
Anda seharusnya dapat menggunakan panggilan "client.ResponseHeaders [..]", lihat tautan ini untuk contoh mendapatkan barang kembali dari tanggapan
sumber
Anda dapat mencoba kode ini untuk mendapatkan kode status HTTP dari WebException atau dari OpenReadCompletedEventArgs.Error. Ia bekerja di Silverlight juga karena SL tidak memiliki WebExceptionStatus.ProtocolError yang ditentukan.
HttpStatusCode GetHttpStatusCode(System.Exception err) { if (err is WebException) { WebException we = (WebException)err; if (we.Response is HttpWebResponse) { HttpWebResponse response = (HttpWebResponse)we.Response; return response.StatusCode; } } return 0; }
sumber