รหัสสถานะ System.Net.WebException HTTP


คำตอบ:


248

อาจจะเป็นสิ่งนี้ ...

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

แต่ในกรณีของข้อยกเว้น "connectfailure" ของ webexception ฉันได้รับการตอบสนองเป็นโมฆะในกรณีนั้นฉันจะรับรหัส httpstatus ได้อย่างไร
Rusty

8
@ สนิม: คุณทำไม่ได้ หากมีความล้มเหลวในการเชื่อมต่อจะไม่มีรหัสสถานะ HTTP ที่จะได้รับ
LukeH

4
หากข้อผิดพลาดเป็น ProtocolError คุณไม่จำเป็นต้องตรวจสอบการตอบสนองสำหรับโมฆะ ดูความคิดเห็นในตัวอย่างในหน้า MSDN นี้
Andras Toth

5
@AndrasToth แต่เครื่องมือเช่น ReSharper จะให้คำเตือนหากคุณไม่ใช้ null-check และไม่ว่าในกรณีใดมันเป็นแนวปฏิบัติที่ดีในการใช้รหัสป้องกัน
Tom Lint

1
รับค่าHTTP Substatusอย่างไร ตัวอย่างเช่น404.13 ความยาวเนื้อหามีขนาดใหญ่เกินไปการอ้างอิง : docs.microsoft.com/en-us/iis/configuration/system.webServer/ …
Kiquenet

27

โดยใช้ตัวดำเนินการnull เงื่อนไข ( ?.) คุณจะได้รับรหัสสถานะ HTTP ด้วยรหัสบรรทัดเดียว:

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

ตัวแปรจะมีstatus HttpStatusCodeเมื่อมีความล้มเหลวทั่วไปมากขึ้นเช่นข้อผิดพลาดเครือข่ายที่ไม่มีรหัสสถานะ HTTP ที่เคยส่งมาแล้วstatusจะเป็นโมฆะ ในกรณีที่คุณสามารถตรวจสอบที่จะได้รับex.StatusWebExceptionStatus

หากคุณต้องการให้สตริงคำอธิบายเพื่อเข้าสู่ระบบในกรณีที่เกิดความล้มเหลวคุณสามารถใช้ตัวดำเนินการnull-coalescing ( ??) เพื่อรับข้อผิดพลาดที่เกี่ยวข้อง:

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

หากมีการโยนข้อยกเว้นอันเป็นผลมาจากรหัสสถานะ 404 HTTP สตริงจะมี "NotFound" ในทางตรงกันข้ามถ้าเซิร์ฟเวอร์ออฟไลน์สตริงจะมี "ConnectFailure" และอื่น ๆ

(และสำหรับใครก็ตามที่ต้องการทราบวิธีรับรหัสย่อย HTTP นั้นเป็นไปไม่ได้มันเป็นแนวคิดของ Microsoft IIS ที่จะเข้าสู่ระบบบนเซิร์ฟเวอร์เท่านั้นและไม่เคยส่งไปยังไคลเอนต์)


ไม่แน่ใจว่าตัว?.ดำเนินการเดิมชื่อตัวดำเนินการการเผยแพร่ว่างหรือตัวดำเนินการ null ตามเงื่อนไขในระหว่างการเปิดตัวตัวอย่าง แต่ผู้ตรวจสอบ Atlassian ให้คำเตือนให้ใช้โอเปอเรเตอร์การขยายสัญญาณว่างในสถานการณ์ดังกล่าว ยินดีที่ได้ทราบว่ามันจะเรียกว่าตัวดำเนินการ null เงื่อนไข
RBT

1
สายไปถึงฝ่ายนี้เล็กน้อย แต่เตือนอย่างเป็นธรรมว่าตัวดำเนินการที่มีเงื่อนไขเป็นคุณลักษณะ C # 6.0 ดังนั้นจึงจำเป็นต้องใช้คอมไพเลอร์ที่รองรับ คำตอบที่กองมากเกินรายละเอียดเพิ่มเติม VS 2015+ มีเป็นค่าเริ่มต้น แต่ถ้าหากใครใช้สภาพแวดล้อมการสร้าง / ปรับใช้ใด ๆ นอกเหนือจาก "เครื่องของพวกเขา" สิ่งอื่น ๆ อาจต้องนำมาพิจารณาด้วย
CodeHxr

9

สิ่งนี้จะทำงานได้ก็ต่อเมื่อ WebResponse เป็น HttpWebResponse

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

ทำไมต้องจัดการกับ 401-Unauthorized แทนรหัสสถานะ HTTP ที่เป็นไปได้ทั้งหมด? นี่คือคำตอบที่เลวร้ายที่สุด
ympostor

4
@ympostor นี่เป็นเพียงตัวอย่าง นักพัฒนาที่มีเหตุผลเข้าใจสิ่งนี้ ความคิดเห็นของคุณเป็นสิ่งที่ไร้สาระที่สุดที่ฉันเคยอ่านที่นี่
pr0gg3r

9

(ฉันรู้ว่าคำถามนั้นเก่า แต่เป็นหนึ่งในเพลงยอดนิยมใน 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)

ในที่สุด: โปรดทราบว่าไม่จำเป็นต้องโยนข้อยกเว้นอีกครั้งในประโยคจับเมื่อไม่ตรงกับเกณฑ์ของคุณเนื่องจากเราไม่ได้ป้อนข้อในสถานที่แรกด้วยการแก้ปัญหาข้างต้น


4

คุณสามารถลองใช้รหัสนี้เพื่อรับรหัสสถานะ 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;
}

1
return 0? หรือดีกว่าHttpStatusCode?(เป็นโมฆะ )?
Kiquenet

จะใช้งานได้ไหม var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
FMFF

ฉันไม่เข้าใจสิ่งที่คุณต้องการจะทำในตัวอย่างนี้ ในกรณีใดบ้างที่คุณต้องการให้บันทึกกิจกรรม
Sergey

1

ฉันไม่แน่ใจว่ามี แต่ถ้ามีคุณสมบัติดังกล่าวจะไม่ถือว่าเชื่อถือได้ A WebExceptionสามารถเริ่มทำงานได้ด้วยเหตุผลอื่นนอกเหนือจากรหัสข้อผิดพลาด HTTP รวมถึงข้อผิดพลาดของเครือข่ายอย่างง่าย สิ่งเหล่านั้นไม่มีรหัสข้อผิดพลาด http ที่ตรงกันเช่นนั้น

คุณช่วยให้ข้อมูลเพิ่มเติมกับเราเกี่ยวกับสิ่งที่คุณพยายามทำให้สำเร็จด้วยรหัสนั้นได้หรือไม่ อาจมีวิธีที่ดีกว่าในการรับข้อมูลที่คุณต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.