ฉันจะรับ StatusCode จาก HttpRequestException ได้อย่างไร


90

ฉันอาจจะขาดอะไรบางอย่างที่ชัดเจนที่นี่

ฉันกำลังใช้การHttpClientพ่นHttpRequestExceptionที่มีStatusCodeในสตริงข้อความ

ฉันจะเข้าถึงสิ่งนั้นได้StatusCodeอย่างไร


แก้ไข : ข้อมูลเพิ่มเติมฉันเขียนคำถามนี้อย่างเร่งด่วน

ฉันกำลังใช้HttpClientเพื่อเข้าถึง API อื่นภายในโครงการ WebApi ของฉัน ใช่ฉันรู้ว่าทำไมฉันถึงโทรEnsureSuccessStatusCode()มา ฉันต้องการเผยแพร่ข้อผิดพลาดบางอย่างที่อยู่ด้านล่างเช่น 404 และ 403

สิ่งที่ฉันต้องการคือเปลี่ยนHttpRequestExceptionเป็นการHttpResponseExceptionใช้แบบกำหนดเองExceptionFilterAttributeอย่างสม่ำเสมอ

น่าเสียดายที่HttpRequestExceptionไม่มีข้อมูลเพิ่มเติมใด ๆ ที่ฉันสามารถใช้ได้นอกจากข้อความ ฉันหวังว่าจะค้นพบStatusCodeในรูปแบบดิบ (int หรือ enum)

ดูเหมือนว่าฉันสามารถ:

  1. ใช้ข้อความเพื่อเปลี่ยนรหัสสถานะ (bleh)
  2. หรือสร้าง SureSuccessStatusCode เวอร์ชันของฉันและโยนข้อยกเว้นที่ใช้งานได้จริง

1
คุณสามารถแสดงรหัสได้หรือไม่?
Hamlet Hakobyan

1
"เข้าถึงรหัสสถานะนั้น" หมายความว่าอย่างไร
Marco

แสดงรหัสบอกตำแหน่งที่คุณได้รับข้อยกเว้น
เดนมาร์ก

5
มีอะไรไม่ชัดเจนเกี่ยวกับชื่อคำถามนี้
Kugel

1
คุณหาวิธีแก้ปัญหานี้ได้อย่างเหมาะสมหรือไม่? โปรดแบ่งปัน
Siddharth Pandey

คำตอบ:


38

รหัสสถานะถูกส่งผ่านเป็นส่วนหนึ่งของสตริงHttpRequestExceptionเพื่อที่คุณจะไม่สามารถกู้คืนจากข้อยกเว้นดังกล่าวเพียงอย่างเดียว

การออกแบบSystem.Net.Httpต้องการให้คุณเข้าถึงHttpResponseMessage.StatusCodeแทนที่จะรอข้อยกเว้น

http://msdn.microsoft.com/en-us/library/system.net.http.httpresponsemessage(v=vs.110).aspx

หากคุณกำลังติดตามคู่มือไมโครซอฟท์HttpResponseMessage.EnsureSucessStatusCodeให้แน่ใจว่าคุณเข้าใจอย่างชัดเจนว่าทำไมมันขอให้คุณโทร หากคุณไม่เรียกใช้ฟังก์ชันนั้นก็ไม่มีข้อยกเว้น


2
ฉันกำลังพยายามจัดการกับข้อกังวลในการตัดกันที่นี่ ดูการแก้ไขของฉันอาจมีทางออกที่ดีกว่า
Kugel

1
สิ่งนี้เหมาะกับการใช้ HttpClient.GetStreamAsync (url) หรือไม่เนื่องจากฉันไม่เห็นวิธีดำเนินการนี้โดยไม่ต้องตัดข้อความออก
วุฒิสมาชิก

1
@TheSenator คุณต้องเรียก GetAsync (uri) หรือ PostAsync (uri) เพื่อรับ HttpResponseMessage กลับคืนมา หากคุณพยายามและรับเนื้อหาของการตอบกลับโดยการอ่านหรือใช้วิธีการอำนวยความสะดวกเช่น GetStreamAsync จะเรียกว่า SureSuccessStatusCode ภายใต้ประทุน
61

7
ซึ่งทำให้เกิดคำถามที่ชัดเจนว่าอะไรคือจุดสำคัญของวิธีการอำนวยความสะดวกที่พร้อมใช้งานหากพวกเขาโยนข้อยกเว้นที่ไม่ทำให้สามารถจัดการกับข้อผิดพลาดได้อย่างมีประโยชน์ การทิ้งโค้ดของคุณด้วยคำสั่ง if and throw ไม่ใช่วิธีแก้ปัญหาดังนั้นจากสิ่งที่ได้กล่าวไว้ในที่นี้คำตอบที่ถูกต้องในปัจจุบันคือคุณต้องนำวิธีการอำนวยความสะดวกหรือการตรวจสอบให้แน่ใจอีกครั้งด้วยตัวคุณเอง
Neutrino

1
พูดง่ายกว่าทำ ข้อยกเว้นสามารถโยนออกจากรหัสของบุคคลที่สาม ตัวอย่างเช่นไคลเอ็นต์ผยองที่สร้างขึ้นโดยอัตโนมัติ
user2555515

27

เพื่อสิ่งที่คุ้มค่าผู้ชายคนนี้ทำสิ่งที่ฉลาด: https://social.msdn.microsoft.com/Forums/vstudio/en-US/dc9bc426-1654-4319-a7fb-383f00b68def/c-httpresponsemessage-throws-exception-httprequestexception -webexception-the-remote-name? forum = csharpgeneral

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

catch (HttpRequestException requestException)
{
    if (requestException.InnerException is WebException webException && webException.Status == WebExceptionStatus.NameResolutionFailure)
    {
        return true;
    }

    return false;
}

14
โหวตขึ้นเนื่องจากบางครั้งคุณไม่สามารถเข้าถึงการตอบกลับได้เช่นเมื่อคุณถูกบังคับให้ใช้ไลบรารีที่ครอบคลุมฟังก์ชันการทำงานและแสดงข้อยกเว้นใด ๆ
Kell

4
. net core 2.1 HttpClient มี GetAsync () และ GetStreamAsync () รายการแรกจะส่งคืนการตอบกลับในขณะที่อีกรายการหนึ่งจะเรียกใช้ SureSucessStatusCode ภายในและโยน HttpRequestException ฉันไม่เข้าใจความไม่สอดคล้องกันและทำให้จัดการข้อผิดพลาดได้ยาก แต่ฉันขอขอบคุณวิธีแก้ปัญหานี้
smurtagh

3
การเรียกใช้. NET Core 3.1.5 requestException.InnerExceptionเป็นโมฆะจึงใช้ไม่ได้
Ohad Schneider

3

ดังที่ผู้อื่นกล่าวไว้เช่นกันการรับ StatusCode จาก HttpRequestException นั้นไม่ใช่แนวทางปฏิบัติที่ดีสามารถทำได้เช่นเดียวกันกับ HttpResponseMessage.StatusCode หลังจากตรวจสอบ HttpResponseMessage.IsSuccessStatusCode

อย่างไรก็ตามหากเนื่องจากข้อ จำกัด / ข้อกำหนดบางประการต้องอ่าน StatusCode อาจมีสองวิธีแก้ปัญหา

  1. ขยาย HttpResponseMessage ด้วยข้อยกเว้นที่กำหนดเองของคุณอธิบายไว้ที่นี่
  2. แฮ็ก HttpRequestException ToString เพื่อรับ StatusCode เนื่องจากข้อความเป็นโพสต์คงที่แก้ไขโดย StatusCode และ Repharse

ด้านล่างนี้คือรหัสใน System.Net.Http.HttpResponseMessage โดยที่ SR.net_http_message_not_success_statuscode = "รหัสสถานะการตอบกลับไม่ได้ระบุความสำเร็จ: {0} ({1})"

public HttpResponseMessage EnsureSuccessStatusCode()
    {
        if (!this.IsSuccessStatusCode)
        {
            if (this.content != null)
            {
                this.content.Dispose();
            }
            throw new HttpRequestException(string.Format(CultureInfo.InvariantCulture, SR.net_http_message_not_success_statuscode, new object[]
            {
                (int)this.statusCode,
                this.ReasonPhrase
            }));
        }
        return this;
    }

4
สตริงข้อผิดพลาดที่มีรูปแบบเฉพาะเป็นกลิ่นรหัสตรรกะไม่ควรขึ้นอยู่กับสิ่งเหล่านี้
user1496062

1
@ user1496062 เมื่อเกิดข้อผิดพลาดจากระบบภายนอกมักไม่มีทางเลือกอื่น
Ian Warburton

1

สิ่งนี้ได้ผลสำหรับฉัน

var response = ex.Response;
var property = response.GetType().GetProperty("StatusCode");
if ( property != null && (HttpStatusCode)property.GetValue(response) == HttpStatusCode.InternalServerError)

0

บางทีฉันอาจจะมาสายที่นี่:

จาก. NET 5.0 HttpRequestExceptionมีStatusCodeคุณสมบัติซึ่งจะมีค่าหากข้อยกเว้นแสดงถึงผลลัพธ์ที่ไม่สำเร็จมิฉะนั้นจะเป็นค่าว่าง คุณสามารถใช้ดังนี้:

try
{
   // Your code
}
catch (HttpRequestException httpRequestException)
{
   if ((int)httpRequestException.StatusCode == 401)
   {
        // Show unauthorized error message
   }
   else 
   {
       // Other error message
   }
}

สำหรับรายละเอียดเพิ่มเติมอยู่ที่นี่

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