c# - لغة - سي شارب عربي




كيفية الحصول على رمز الحالة من webclient؟ (7)

أستخدم فئة WebClient لنشر بعض البيانات إلى نموذج ويب. أرغب في الحصول على رمز حالة الاستجابة الخاص بتقديم النموذج. حتى الآن ، اكتشفت كيفية الحصول على رمز الحالة إذا كان هناك استثناء

Catch wex As WebException
        If TypeOf wex.Response Is HttpWebResponse Then
          msgbox(DirectCast(wex.Response, HttpWebResponse).StatusCode)
            End If

ولكن إذا تم إرسال النموذج بنجاح ولم يتم طرح أي استثناء ، فلن أعرف رمز الحالة (200،301،302 ، ...)

هل هناك طريقة للحصول على رمز الحالة في حالة عدم وجود استثناءات؟

ملاحظة: أنا أفضل عدم استخدام httpwebrequest / httpwebresponse


حاولت بها. لا تحتوى جهات الاستجابة على رمز الحالة.

إذا لم أكن مخطئًا ، WebClient قادرًا على التخلص من الطلبات المتميزة المتعددة في مكالمة طريقة واحدة (على سبيل المثال ، معالجة 100 استجابة مستمرة ، وعمليات إعادة التوجيه ، وما شابه). أعتقد أنه بدون استخدام HttpWebRequest و HttpWebResponse ، قد لا يتوفر رمز حالة مميزة.

ويحدث لي أنه إذا لم تكن مهتمًا برموز الحالة المتوسطة ، فيمكنك أن تفترض بأمان أن رمز الحالة النهائي في النطاق 2xx (الناجحة) ، وإلا لن تنجح المكالمة.

رمز الحالة للأسف غير موجود في القاموس ResponseHeaders .


طريق اخر:

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

لا تعمل إجابة إريك على Windows Phone كما هي. ما يلي هو:

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

على الأقل يفعل ذلك عند استخدام OpenReadAsync . بالنسبة لطرق xxxAsync الأخرى ، xxxAsync بإجراء اختبار دقيق. يستدعي إطار العمل GetWebResponse في مكان ما على مسار التعليمات البرمجية؛ كل ما عليك القيام به هو التقاط وتخزين كائن الاستجابة.

رمز التراجع هو 200 في هذا المقتطف لأن أخطاء HTTP الحقيقية - 500 و 404 وما إلى ذلك - يتم الإبلاغ عنها كإستثناءات على أي حال. الغرض من هذه الخدعة هو التقاط رموز غير خطأ ، في حالتي الخاصة 304 (لم يتم تعديلها). لذا ، يفترض الاحتياط أنه إذا كان رمز الحالة غير متاح على نحو ما ، فعلى الأقل يكون رمزًا غير خاطئ.


هذا ما أستخدمه لتوسيع وظائف WebClient. سيحتوي StatusCode و StatusDescription دائمًا على أحدث رمز / وصف استجابة.

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

وبالتالي يمكنك إجراء مشاركة والحصول على النتيجة عبر:

            byte[] response = null;
            using (WebClientCert client = new WebClientCert())
            {
                response = client.UploadValues(postUri, PostFields);
                HttpStatusCode code = client.StatusCode;
                string description = client.StatusDescription;
                //Use this information
            }

يجب أن تكون قادرًا على استخدام استدعاء "client.ResponseHeaders [..]" ، راجع هذا link للحصول على أمثلة لاستعادة الحالة من الرد


يجب عليك استخدامها

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

يمكنك تجربة هذا الرمز للحصول على رمز حالة HTTP من WebException أو من OpenReadCompletedEventArgs.Error. وهو يعمل في Silverlight أيضا لأن SL ليس لديها 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;
}






webclient