سؤال

هل هناك طريقة سهلة للحصول على رمز حالة HTTP من أ System.Net.WebException?

هل كانت مفيدة؟

المحلول

ربما شيء من هذا القبيل ...

try
{
    // ...
}
catch (WebException ex)
{
    if (ex.Status == WebExceptionStatus.ProtocolError)
    {
        var response = ex.Response as HttpWebResponse;
        if (response != null)
        {
            Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
        }
        else
        {
            // no http status code available
        }
    }
    else
    {
        // no http status code available
    }
}

نصائح أخرى

باستخدام مشغل فارغ (?.) يمكنك الحصول على رمز حالة HTTP مع سطر واحد من التعليمات البرمجية:

 HttpStatusCode? status = (ex.Response as HttpWebResponse)?.StatusCode;

المتغير status سوف تحتوي على HttpStatusCode. عندما يكون هناك فشل أكثر عمومية مثل خطأ في الشبكة حيث لم يتم إرسال رمز حالة HTTP بعد ذلك على الإطلاق status سيكون فارغا. في هذه الحالة يمكنك فحص ex.Status للحصول على WebExceptionStatus.

إذا كنت تريد فقط سلسلة وصفية لتسجيل الدخول إلى حالة الفشل ، يمكنك استخدام مشغل coalescing فارغ (??) للحصول على الخطأ ذي الصلة:

string status = (ex.Response as HttpWebResponse)?.StatusCode.ToString()
    ?? ex.Status.ToString();

إذا تم طرح الاستثناء نتيجة لرمز حالة HTTP 404 ، فستتضمن السلسلة "Notfound". من ناحية أخرى ، إذا كان الخادم غير متصل بالإنترنت ، فسوف يحتوي السلسلة على "ConnectFailure" وما إلى ذلك.

(ولأي شخص يريد معرفة كيفية الحصول على رمز HTTP Substatus. هذا غير ممكن. إنه مفهوم Microsoft IIS الذي يتم تسجيله فقط على الخادم ولم يتم إرساله إلى العميل أبدًا.)

هذا لا يعمل إلا إذا كان webresponse هو httpwebropsebonse.

try
{
    ...
}
catch (System.Net.WebException exc)
{
    var webResponse = exc.Response as System.Net.HttpWebResponse;
    if (webResponse != null && 
        webResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
    {
        MessageBox.Show("401");
    }
    else
        throw;
}

(أدرك أن السؤال قديم ، لكنه من بين أفضل الزيارات على Google.)

موقف شائع حيث تريد معرفة رمز الاستجابة في معالجة استثناء. اعتبارًا من C# 7 ، يمكنك استخدام مطابقة الأنماط للدخول إلى شرط Catch فقط إذا كان الاستثناء يتطابق مع مسندك:

catch (WebException ex) when (ex.Response is HttpWebResponse response)
{
     doSomething(response.StatusCode)
}

يمكن بسهولة تمديد هذا إلى مستويات أخرى ، كما هو الحال في هذه الحالة WebException كان في الواقع الاستثناء الداخلي لآخر (ونحن مهتمون فقط 404):

catch (StorageException ex) when (ex.InnerException is WebException wex && wex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.NotFound)

أخيرًا: لاحظ كيف لا توجد حاجة لإعادة تقديم الاستثناء في جملة Catch عندما لا تتطابق مع معاييرك ، نظرًا لأننا لا ندخل البند في المقام الأول مع الحل أعلاه.

يمكنك تجربة هذا الرمز للحصول على رمز حالة HTTP من WebException. إنه يعمل في Silverlight أيضًا لأن SL لا يحتوي على WebExceptionStatus.Protocolerror المحدد.

HttpStatusCode GetHttpStatusCode(WebException we)
{
    if (we.Response is HttpWebResponse)
    {
        HttpWebResponse response = (HttpWebResponse)we.Response;
        return response.StatusCode;
    }
    return null;
}

لست متأكدًا مما إذا كان هناك ولكن إذا كان هناك مثل هذه الخاصية ، فلن يعتبر موثوقًا به. أ WebException يمكن إطلاقها لأسباب أخرى غير رموز خطأ HTTP بما في ذلك أخطاء الشبكات البسيطة. هؤلاء ليس لديهم رمز خطأ HTTP مطابق.

هل يمكنك أن تعطينا المزيد من المعلومات حول ما تحاول تحقيقه باستخدام هذا الرمز. قد تكون هناك طريقة أفضل للحصول على المعلومات التي تحتاجها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top