Pertanyaan Bagaimana cara mendapatkan kode status dari webclient?


Saya menggunakan WebClient kelas untuk memposting beberapa data ke formulir web. Saya ingin mendapatkan kode status respons dari pengiriman formulir. Sejauh ini saya sudah 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 dikirimkan dan tidak ada pengecualian yang terlempar maka saya tidak akan tahu kode status (200.301.302, ...)

Apakah ada cara untuk mendapatkan kode status ketika tidak ada pengecualian yang dilemparkan?

PS: Saya lebih suka tidak menggunakan httpwebrequest / httpwebresponse


75
2017-08-26 11:33


asal


Jawaban:


Sudah mencobanya. ResponseHeaders tidak termasuk kode status.

Jika aku tidak salah, WebClient mampu mengabstraksikan beberapa permintaan berbeda dalam satu pemanggilan metode (mis. menangani 100 tanggapan Lanjutkan, pengalihan, dan sejenisnya dengan benar). Saya menduga bahwa tanpa menggunakan HttpWebRequest dan HttpWebResponse, kode status yang berbeda mungkin tidak tersedia.

Itu terjadi pada saya bahwa, jika Anda tidak tertarik dengan kode status menengah, Anda dapat dengan aman menganggap kode status terakhir dalam 2xx (berhasil), jika tidak, panggilan tidak akan berhasil.

Kode status sayangnya tidak ada di ResponseHeaders kamus.


20
2017-08-26 11:43



Anda dapat memeriksa apakah kesalahan itu bertipe WebException dan kemudian periksa kode respon;

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..
}

73
2018-02-09 15:37



Ada cara untuk melakukannya menggunakan refleksi. Ia bekerja dengan .NET 4.0. Ini mengakses bidang pribadi dan mungkin tidak berfungsi di versi lain. NET tanpa modifikasi.

Saya tidak tahu mengapa Microsoft tidak mengekspos bidang ini dengan sebuah 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;
}

27
2018-06-24 15:56



Cara lain:

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;
        }
    }

23
2017-08-31 06:26



Jawaban Erik tidak berfungsi di Windows Phone apa adanya. Hal-hal berikut ini:

class WebClientEx : WebClient
{
    private WebResponse m_Resp = null;

    protected override WebResponse GetWebResponse(WebRequest Req, IAsyncResult ar)
    {
        return m_Resp = base.GetWebResponse(Req, ar);
    }

    public HttpStatusCode StatusCode
    {
        get
        {
            if (m_Resp != null && m_Resp is HttpWebResponse)
                return (m_Resp as HttpWebResponse).StatusCode;
            else
                return HttpStatusCode.OK;
        }
    }
}

Setidaknya itu saat menggunakan OpenReadAsync; untuk yang lain xxxAsync metode, pengujian yang cermat akan sangat dianjurkan. Kerangka kerja ini memanggil GetWebResponse di suatu tempat di sepanjang jalur kode; yang perlu dilakukan adalah menangkap dan menyimpan objek respons.

Kode fallback adalah 200 dalam snippet ini karena kesalahan HTTP asli - 500, 404, dll - 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 itu salah satu yang tidak salah.


6
2017-11-13 16:42



Kamu harus menggunakan

if (e.Status == WebExceptionStatus.ProtocolError)
{
   HttpWebResponse response = (HttpWebResponse)ex.Response;             
   if (response.StatusCode == HttpStatusCode.NotFound)
      System.Diagnostics.Debug.WriteLine("Not found!");
}

2
2017-08-21 09:33



Untuk berjaga-jaga orang lain memerlukan 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()

1
2017-11-25 18:13



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 hasil 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
            }

1
2017-10-03 22:03



Anda harus dapat menggunakan panggilan "client.ResponseHeaders [..]", lihat ini link untuk contoh mendapatkan kembali barang dari respons


-1
2017-08-26 11:44



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 definisi WebExceptionStatus.ProtocolError.

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;
}

-1
2017-12-09 09:54