Wie erhalte ich StatusCode von HttpRequestException?

87

Ich vermisse hier wahrscheinlich etwas Offensichtliches.

Ich verwende HttpClientdie Würfe HttpRequestException, die StatusCodein der Nachrichtenzeichenfolge enthalten sind.

Wie kann ich darauf zugreifen StatusCode?


Edit : Mehr Infos, ich habe diese Frage in Eile geschrieben.

Ich verwende, HttpClientum auf eine andere API in meinem WebApi-Projekt zuzugreifen. Ja, ich weiß warum ich anrufe EnsureSuccessStatusCode(). Ich möchte einige Fehler nachgelagert verbreiten, wie z. B. 404 und 403.

Alles, was ich wollte, war, mich konsequent HttpRequestExceptionin die HttpResponseExceptionVerwendung von Gewohnheiten zu verwandeln ExceptionFilterAttribute.

Enthält leider HttpRequestExceptionkeine zusätzlichen Informationen, die ich neben der Nachricht verwenden könnte. Ich hatte gehofft, StatusCodein roher (int oder enum) Form aufzudecken .

Sieht so aus, als könnte ich entweder:

  1. Verwenden Sie die Nachricht, um den Statuscode zu wechseln (bleh)
  2. Oder erstellen Sie meine Version von EnsureSuccessStatusCode und lösen Sie eine Ausnahme aus, die tatsächlich verwendet werden kann.
Kugel
quelle
1
Können Sie einen Code zeigen?
Hamlet Hakobyan
1
Was meinst du mit "Zugriff auf diesen Statuscode"?
Marco
Zeigen Sie dem Code an, wo Sie die Ausnahme erhalten.
Dänisch
5
Leute, was ist nicht klar über den Titel dieser Frage?
Kugel
1
Haben Sie es geschafft, eine geeignete Lösung für dieses Problem zu finden? Bitte teilen
Siddharth Pandey

Antworten:

37

Der Statuscode wurde als Teil einer Zeichenfolge an übergeben, HttpRequestExceptiondamit Sie ihn nicht allein aus solchen Ausnahmen wiederherstellen können.

Für das Design von System.Net.Httpmüssen Sie zugreifen, HttpResponseMessage.StatusCodeanstatt auf die Ausnahme zu warten.

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

Wenn Sie jetzt dem Microsoft-Handbuch folgen , stellen Sie sicher, dass Sie genau verstehen, warum Sie dazu aufgefordert werden, anzurufen HttpResponseMessage.EnsureSucessStatusCode. Wenn Sie diese Funktion nicht aufrufen, sollte es keine Ausnahme geben.

Lex Li
quelle
2
Ich versuche hier ein Querschnittsthema anzusprechen. Schauen Sie sich meine Bearbeitung an, vielleicht gibt es eine bessere Lösung.
Kugel
1
Passt dies zur Verwendung von HttpClient.GetStreamAsync (url), da ich keine Möglichkeit sehe, diese Aktion auszuführen, ohne den Nachrichtentext entfernen zu müssen?
Der Senator
1
@TheSenator Sie müssen GetAsync (uri) oder PostAsync (uri) aufrufen, um eine HttpResponseMessage zurückzugewinnen. Wenn Sie versuchen, den Inhalt der Antwort entweder durch Lesen oder mithilfe einer praktischen Methode wie GetStreamAsync zu ermitteln, wird EnsureSuccessStatusCode unter der Haube aufgerufen.
odyth
6
Was die offensichtliche Frage aufwirft, wozu die Convenience-Methoden überhaupt verfügbar sind, wenn sie Ausnahmen auslösen, die es nicht ermöglichen, den Fehler sinnvoll zu behandeln. Es ist keine Lösung, Ihren Code mit if- und throw-Anweisungen zu verunreinigen. Nach dem, was hier gesagt wurde, scheint die richtige Antwort derzeit zu sein, dass Sie entweder die Convenience-Methoden oder EnsureSuccessStatusCode selbst neu implementieren müssen.
Neutrino
1
Das ist einfacher gesagt als getan. Die Ausnahme kann von einem Code eines Drittanbieters ausgelöst werden. Zum Beispiel automatisch generierter Swagger-Client.
user2555515
27

Für was es wert ist, hat dieser Typ etwas Kluges getan: 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

In dem Fall, in dem ich eine Ausnahmestatus-Eigenschaft benötigte, kann ich Folgendes tun:

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

    return false;
}
Steve
quelle
14
Up-Voted, weil Sie manchmal keinen Zugriff auf die Antwort haben, beispielsweise wenn Sie gezwungen sind, eine Bibliothek zu verwenden, die die Funktionalität einschließt und Ausnahmen auslöst.
Kell
4
Der .net Core 2.1 HttpClient verfügt über GetAsync () und GetStreamAsync (). Der erste gibt eine Antwort zurück, während der andere EnsureSucessStatusCode intern aufruft und eine HttpRequestException auslöst. Ich verstehe die Inkonsistenz nicht und es erschwert die Behandlung von Fehlern, aber ich schätze diese Problemumgehung.
Smurtagh
2
Das Ausführen von .NET Core 3.1.5 requestException.InnerExceptionist null, daher funktioniert dies nicht
Ohad Schneider,
3

Wie auch von anderen erwähnt, ist es keine gute Praxis, den StatusCode von HttpRequestException abzurufen. Dies kann zuvor mit HttpResponseMessage.StatusCode durchgeführt werden, nachdem HttpResponseMessage.IsSuccessStatusCode überprüft wurde

Auf jeden Fall kann es zwei Lösungen geben, wenn aufgrund einer Einschränkung / Anforderung StatusCode gelesen werden muss

  1. Erweitert die HttpResponseMessage um Ihre hier erläuterte benutzerdefinierte Ausnahme
  2. Hacken Sie die HttpRequestException.ToString, um den StatusCode abzurufen, da die Nachricht ein konstanter Beitrag ist, der durch StatusCode und Repharse behoben wurde.

Unten finden Sie den Code in System.Net.Http.HttpResponseMessage, wobei SR.net_http_message_not_success_statuscode = "Der Antwortstatuscode zeigt keinen Erfolg an: {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;
    }
Surender Singh Malik
quelle
4
Fehlerzeichenfolgen mit einem bestimmten Format sind ein Codegeruch, die Logik sollte niemals von ihnen abhängen.
user1496062
1
@ user1496062 Wenn Fehler von einem externen System kommen, gibt es oft keine Alternative.
Ian Warburton
1

Das hat bei mir funktioniert

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