Freigeben über


Ausführen von HTTP-Anforderungen mit der HttpClient-Klasse

In diesem Artikel erfahren Sie, wie Sie HTTP-Anforderungen vornehmen und Antworten mit der HttpClient Klasse behandeln.

Wichtig

Alle BEISPIEL-HTTP-Anforderungen in diesem Artikel zielen auf eine der folgenden URLs ab:

HTTP-Endpunkte geben häufig JSON-Daten (JavaScript Object Notation) zurück, aber nicht immer. Zur Vereinfachung stellt das optionale System.Net.Http.Json NuGet-Paket mehrere Erweiterungsmethoden für HttpClient und HttpContent Objekte bereit, die automatische Serialisierung und Deserialisierung mithilfe des 📦 System.Text.Json NuGet-Pakets ausführen. Die Beispiele in diesem Artikel beziehen sich auf Orte, an denen diese Erweiterungen verfügbar sind.

Tipp

Der in diesem Artikel referenzierte Quellcode ist im GitHub:.NET Docs-Repository verfügbar.

Erstellen eines HttpClient-Objekts

Die meisten Beispiele in diesem Artikel verwenden dieselbe HttpClient Instanz, sodass Sie die Instanz einmal konfigurieren und für die verbleibenden Beispiele verwenden können. Verwenden Sie den HttpClient Klassenkonstruktor, um ein HttpClient Objekt zu erstellen. Weitere Informationen finden Sie unter Richtlinien für die Verwendung von HttpClient.

// HttpClient lifecycle management best practices:
// https://learn.microsoft.com/dotnet/fundamentals/networking/http/httpclient-guidelines#recommended-use
private static HttpClient sharedClient = new()
{
    BaseAddress = new Uri("https://jsonplaceholder.typicode.com"),
};

Der Code schließt die folgenden Aufgaben ab:

  • Instanziieren Sie eine neue HttpClient Instanz als static Variable. Gemäß den Richtlinien wird empfohlen, Instanzen während des Anwendungslebenszyklus wiederzuverwenden HttpClient .
  • Legen Sie die HttpClient.BaseAddress-Eigenschaft auf "https://jsonplaceholder.typicode.com" fest.

Diese HttpClient Instanz verwendet die Basisadresse, um nachfolgende Anforderungen zu stellen. Um andere Konfigurationen anzuwenden, berücksichtigen Sie die folgenden APIs:

Tipp

Alternativ können Sie HttpClient-Instanzen mithilfe eines Factorymusteransatzes erstellen, der es Ihnen ermöglicht, eine beliebige Anzahl von Clients zu konfigurieren und diese als Dienst zur Abhängigkeitsinjektion zu verwenden. Weitere Informationen finden Sie unter HTTP-Clientfactory mit .NET.

Senden einer HTTP-Anforderung

Um eine HTTP-Anforderung zu senden, rufen Sie eine der folgenden API-Methoden auf:

HTTP-Methode Programmierschnittstelle (API)
GET HttpClient.GetAsync
GET HttpClient.GetByteArrayAsync
GET HttpClient.GetStreamAsync
GET HttpClient.GetStringAsync
POST HttpClient.PostAsync
PUT HttpClient.PutAsync
PATCH HttpClient.PatchAsync
DELETE HttpClient.DeleteAsync
USER SPECIFIED HttpClient.SendAsync

Eine USER SPECIFIED Anforderung gibt an, dass die SendAsync Methode jedes gültige HttpMethod Objekt akzeptiert.

Warnung

Das Ausführen von HTTP-Anforderungen wird als Netzwerk-E/A-gebundene Arbeit betrachtet. Es ist eine synchrone HttpClient.Send Methode vorhanden, aber die Empfehlung besteht darin, stattdessen die asynchronen APIs zu verwenden, es sei denn, Sie haben keinen guten Grund.

Hinweis

Beim Anvisieren von Android-Geräten (z. B. bei der .NET MAUI-Entwicklung) müssen Sie die android:usesCleartextTraffic="true"-Definition dem <application></application>-Abschnitt in der AndroidManifest.xml-Datei hinzufügen. Diese Einstellung aktiviert Klartextdatenverkehr, z. B. HTTP-Anforderungen, die aufgrund von Android-Sicherheitsrichtlinien andernfalls standardmäßig deaktiviert sind. Betrachten Sie das folgende XML-Beispielszenario:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <application android:usesCleartextTraffic="true"></application>
  <!-- omitted for brevity -->
</manifest>

Weitere Informationen finden Sie unter Aktivieren von Klartext-Netzwerkdatenverkehr für die Domäne localhost.

Grundlegendes zu HTTP-Inhalten

Der Typ HttpContent wird verwendet, um HTTP-Entitätstext und die zugehörigen Inhaltsheader darzustellen. Bei HTTP-Methoden (oder Anforderungsmethoden), die einen Textkörper (POST, , PUT) erfordern, PATCHverwenden Sie die HttpContent Klasse, um den Textkörper der Anforderung anzugeben. Die meisten Beispiele zeigen, wie Sie die StringContent-Unterklasse mit JSON-Nutzdaten vorbereiten, aber es gibt weitere Unterklassen für verschiedene Inhaltstypen (MIME).

  • ByteArrayContent: Stellt HTTP-Inhalt auf der Grundlage eines Bytearrays bereit.
  • FormUrlEncodedContent: Stellt HTTP-Inhalt für namens-/Wert-Tupel bereit, die mithilfe des "application/x-www-form-urlencoded" MIME-Typs codiert werden.
  • JsonContent: Stellt HTTP-Inhalt auf Grundlage von JSON bereit.
  • MultipartContent: Stellt eine Auflistung von HttpContent-Objekten bereit, die mithilfe der "multipart/*" MIME-Typspezifikation serialisiert werden.
  • MultipartFormDataContent: Stellt einen Container für Inhalte bereit, die mithilfe des "multipart/form-data" MIME-Typs codiert werden.
  • ReadOnlyMemoryContent: Stellt HTTP-Inhalte basierend auf einem ReadOnlyMemory<T> Wert bereit.
  • StreamContent: Stellt HTTP-Inhalt auf der Grundlage eines Streams bereit.
  • StringContent: Stellt HTTP-Inhalt auf der Grundlage einer Zeichenfolge bereit.

Die HttpContent Klasse wird auch verwendet, um den Antworttext der HttpResponseMessage Klasse darzustellen, auf die für die HttpResponseMessage.Content Eigenschaft zugegriffen werden kann.

Verwenden einer HTTP GET-Anforderung

Eine GET-Anforderung sollte keinen Inhalt senden. Diese Anforderung wird verwendet (wie der Methodenname angibt), um Daten aus einer Ressource abzurufen (oder abzurufen). Verwenden Sie die GET Methode, um eine HTTP-Anforderung HttpClient für eine Uri Instanz und ein HttpClient.GetAsync Objekt zu erstellen:

static async Task GetAsync(HttpClient httpClient)
{
    using HttpResponseMessage response = await httpClient.GetAsync("todos/3");
    
    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();
    
    var jsonResponse = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"{jsonResponse}\n");

    // Expected output:
    //   GET https://jsonplaceholder.typicode.com/todos/3 HTTP/1.1
    //   {
    //     "userId": 1,
    //     "id": 3,
    //     "title": "fugiat veniam minus",
    //     "completed": false
    //   }
}

Der Code schließt die folgenden Aufgaben ab:

  • Stellen Sie eine GET Anforderung an den "https://jsonplaceholder.typicode.com/todos/3" Endpunkt vor.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist.
  • Schreiben Sie die Anforderungsdetails in die Konsole.
  • Lesen Sie den Antworttext als Zeichenfolge.
  • Schreiben Sie den JSON-Antworttext in die Konsole.

Die WriteRequestToConsole Methode ist eine benutzerdefinierte Erweiterung, die nicht Teil des Frameworks ist. Wenn Sie mehr über die Implementierung wissen möchten, sollten Sie den folgenden C#-Code in Betracht ziehen:

static class HttpResponseMessageExtensions
{
    internal static void WriteRequestToConsole(this HttpResponseMessage response)
    {
        if (response is null)
        {
            return;
        }

        var request = response.RequestMessage;
        Console.Write($"{request?.Method} ");
        Console.Write($"{request?.RequestUri} ");
        Console.WriteLine($"HTTP/{request?.Version}");        
    }
}

Diese Funktionalität wird verwendet, um die Anforderungsdetails in folgender Form in die Konsole einzugeben:

<HTTP Request Method> <Request URI> <HTTP/Version>

Als Beispiel gibt die GET Anforderung an den "https://jsonplaceholder.typicode.com/todos/3" Endpunkt die folgende Meldung aus:

GET https://jsonplaceholder.typicode.com/todos/3 HTTP/1.1

Erstellen der HTTP GET-Anforderung aus JSON

Der https://jsonplaceholder.typicode.com/todos Endpunkt gibt ein JSON-Array von Todo Objekten zurück. Ihre JSON-Struktur ähnelt der folgenden Form:

[
  {
    "userId": 1,
    "id": 1,
    "title": "example title",
    "completed": false
  },
  {
    "userId": 1,
    "id": 2,
    "title": "another example title",
    "completed": true
  },
]

Das C#-Objekt Todo ist wie folgt definiert:

public record class Todo(
    int? UserId = null,
    int? Id = null,
    string? Title = null,
    bool? Completed = null);

Es handelt sich um einen record class-Typ mit den optionalen Eigenschaften Id, Title, Completed und UserId. Weitere Informationen zum Typ record finden Sie unter Einführung in Datensatztypen in C#. Um GET-Anforderungen automatisch in ein stark typisiertes C#-Objekt zu deserialisieren, verwenden Sie die GetFromJsonAsync-Extension-Methode, die Teil des 📦 System.Net.Http.Json-NuGet-Pakets ist.

static async Task GetFromJsonAsync(HttpClient httpClient)
{
    var todos = await httpClient.GetFromJsonAsync<List<Todo>>(
        "todos?userId=1&completed=false");

    Console.WriteLine("GET https://jsonplaceholder.typicode.com/todos?userId=1&completed=false HTTP/1.1");
    todos?.ForEach(Console.WriteLine);
    Console.WriteLine();

    // Expected output:
    //   GET https://jsonplaceholder.typicode.com/todos?userId=1&completed=false HTTP/1.1
    //   Todo { UserId = 1, Id = 1, Title = delectus aut autem, Completed = False }
    //   Todo { UserId = 1, Id = 2, Title = quis ut nam facilis et officia qui, Completed = False }
    //   Todo { UserId = 1, Id = 3, Title = fugiat veniam minus, Completed = False }
    //   Todo { UserId = 1, Id = 5, Title = laboriosam mollitia et enim quasi adipisci quia provident illum, Completed = False }
    //   Todo { UserId = 1, Id = 6, Title = qui ullam ratione quibusdam voluptatem quia omnis, Completed = False }
    //   Todo { UserId = 1, Id = 7, Title = illo expedita consequatur quia in, Completed = False }
    //   Todo { UserId = 1, Id = 9, Title = molestiae perspiciatis ipsa, Completed = False }
    //   Todo { UserId = 1, Id = 13, Title = et doloremque nulla, Completed = False }
    //   Todo { UserId = 1, Id = 18, Title = dolorum est consequatur ea mollitia in culpa, Completed = False }
}

Der Code schließt die folgenden Aufgaben ab:

  • Senden Sie eine GET Anfrage an "https://jsonplaceholder.typicode.com/todos?userId=1&completed=false".

    Die Abfragezeichenfolge repräsentiert die Filterkriterien für die Anforderung. Wenn der Befehl erfolgreich verläuft, wird die Antwort automatisch in ein List<Todo> Objekt deserialisiert.

  • Schreiben Sie die Anforderungsdetails zusammen mit jedem Todo Objekt in die Konsole.

Verwenden einer HTTP POST-Anforderung

Eine POST-Anforderung sendet Daten zur Verarbeitung an den Server. Der Content-Type-Header der Anforderung gibt an, welcher MIME-Typ im Text gesendet wird. Verwenden Sie die POST Methode, um eine HTTP-Anforderung HttpClient für eine Uri Instanz und ein HttpClient.PostAsync Objekt zu erstellen:

static async Task PostAsync(HttpClient httpClient)
{
    using StringContent jsonContent = new(
        JsonSerializer.Serialize(new
        {
            userId = 77,
            id = 1,
            title = "write code sample",
            completed = false
        }),
        Encoding.UTF8,
        "application/json");

    using HttpResponseMessage response = await httpClient.PostAsync(
        "todos",
        jsonContent);

    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();
    
    var jsonResponse = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"{jsonResponse}\n");

    // Expected output:
    //   POST https://jsonplaceholder.typicode.com/todos HTTP/1.1
    //   {
    //     "userId": 77,
    //     "id": 201,
    //     "title": "write code sample",
    //     "completed": false
    //   }
}

Der Code schließt die folgenden Aufgaben ab:

  • Vorbereiten einer StringContent Instanz mit dem JSON-Textkörper der Anforderung (MIME-Typ von "application/json").
  • Stellen Sie eine POST Anforderung an den "https://jsonplaceholder.typicode.com/todos" Endpunkt vor.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails in die Konsole.
  • Schreiben Sie den Antworttext als Zeichenfolge in die Konsole.

Erstellen der HTTP POST-Anforderung als JSON

Um POST-Anforderungsargumente automatisch zu serialisieren und Antworten in stark typisierte C#-Objekte zu deserialisieren, verwenden Sie die Erweiterungsmethode PostAsJsonAsync, die im NuGet-Paket System.Net.Http.Json enthalten ist.

static async Task PostAsJsonAsync(HttpClient httpClient)
{
    using HttpResponseMessage response = await httpClient.PostAsJsonAsync(
        "todos", 
        new Todo(UserId: 9, Id: 99, Title: "Show extensions", Completed: false));

    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();

    var todo = await response.Content.ReadFromJsonAsync<Todo>();
    Console.WriteLine($"{todo}\n");

    // Expected output:
    //   POST https://jsonplaceholder.typicode.com/todos HTTP/1.1
    //   Todo { UserId = 9, Id = 201, Title = Show extensions, Completed = False }
}

Der Code schließt die folgenden Aufgaben ab:

  • Serialisieren Sie die Todo Instanz als JSON, und stellen Sie eine POST Anforderung an den "https://jsonplaceholder.typicode.com/todos" Endpunkt.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails in die Konsole.
  • Deserialisieren Sie den Antworttext in eine Todo Instanz, und schreiben Sie das Todo Objekt in die Konsole.

Verwenden einer HTTP PUT-Anforderung

Die PUT-Anforderungsmethode ersetzt entweder eine vorhandene Ressource oder erstellt eine neue Ressource mithilfe des Anforderungspayloads. Verwenden Sie die PUT Methode, um eine HTTP-Anforderung HttpClient für eine Uri Instanz und ein HttpClient.PutAsync Objekt zu erstellen:

static async Task PutAsync(HttpClient httpClient)
{
    using StringContent jsonContent = new(
        JsonSerializer.Serialize(new 
        {
            userId = 1,
            id = 1,
            title = "foo bar",
            completed = false
        }),
        Encoding.UTF8,
        "application/json");

    using HttpResponseMessage response = await httpClient.PutAsync(
        "todos/1",
        jsonContent);

    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();
    
    var jsonResponse = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"{jsonResponse}\n");

    // Expected output:
    //   PUT https://jsonplaceholder.typicode.com/todos/1 HTTP/1.1
    //   {
    //     "userId": 1,
    //     "id": 1,
    //     "title": "foo bar",
    //     "completed": false
    //   }
}

Der Code schließt die folgenden Aufgaben ab:

  • Vorbereiten einer StringContent Instanz mit dem JSON-Textkörper der Anforderung (MIME-Typ von "application/json").
  • Stellen Sie eine PUT Anforderung an den "https://jsonplaceholder.typicode.com/todos/1" Endpunkt vor.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails mit dem JSON-Antworttext in die Konsole.

Erstellen der HTTP PUT-Anforderung als JSON

Um PUT-Anforderungsargumente automatisch zu serialisieren und Antworten in stark typisierte C#-Objekte zu deserialisieren, verwenden Sie die Erweiterungsmethode PutAsJsonAsync, die im NuGet-Paket System.Net.Http.Json enthalten ist.

static async Task PutAsJsonAsync(HttpClient httpClient)
{
    using HttpResponseMessage response = await httpClient.PutAsJsonAsync(
        "todos/5",
        new Todo(Title: "partially update todo", Completed: true));

    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();

    var todo = await response.Content.ReadFromJsonAsync<Todo>();
    Console.WriteLine($"{todo}\n");

    // Expected output:
    //   PUT https://jsonplaceholder.typicode.com/todos/5 HTTP/1.1
    //   Todo { UserId = , Id = 5, Title = partially update todo, Completed = True }
}

Der Code schließt die folgenden Aufgaben ab:

  • Serialisieren Sie die Todo Instanz als JSON, und stellen Sie eine PUT Anforderung an den "https://jsonplaceholder.typicode.com/todos/5" Endpunkt.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails in die Konsole.
  • Deserialisieren Sie den Antworttext in eine Todo Instanz, und schreiben Sie die Todo Objekte in die Konsole.

Verwenden Sie eine HTTP PATCH-Anforderung

Die PATCH-Anforderung bewirkt eine teilweise Aktualisierung einer vorhandenen Ressource. Diese Anforderung erstellt keine neue Ressource und soll keine vorhandene Ressource ersetzen. Stattdessen aktualisiert diese Methode nur teilweise eine Ressource. Verwenden Sie die PATCH Methode, um eine HTTP-Anforderung HttpClient für eine Uri Instanz und ein HttpClient.PatchAsync Objekt zu erstellen:

static async Task PatchAsync(HttpClient httpClient)
{
    using StringContent jsonContent = new(
        JsonSerializer.Serialize(new
        {
            completed = true
        }),
        Encoding.UTF8,
        "application/json");

    using HttpResponseMessage response = await httpClient.PatchAsync(
        "todos/1",
        jsonContent);

    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();

    var jsonResponse = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"{jsonResponse}\n");

    // Expected output
    //   PATCH https://jsonplaceholder.typicode.com/todos/1 HTTP/1.1
    //   {
    //     "userId": 1,
    //     "id": 1,
    //     "title": "delectus aut autem",
    //     "completed": true
    //   }
}

Der Code schließt die folgenden Aufgaben ab:

  • Vorbereiten einer StringContent Instanz mit dem JSON-Textkörper der Anforderung (MIME-Typ von "application/json").
  • Stellen Sie eine PATCH Anforderung an den "https://jsonplaceholder.typicode.com/todos/1" Endpunkt vor.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails mit dem JSON-Antworttext in die Konsole.

Es gibt keine Erweiterungsmethoden für PATCH-Anforderungen im NuGet-Paket System.Net.Http.Json.

Verwenden einer HTTP DELETE-Anforderung

Eine DELETE Anforderung entfernt eine vorhandene Ressource, und die Anforderung ist idempotent, aber nicht sicher. Mehrere DELETE Anforderungen an dieselben Ressourcen führen zu demselben Ergebnis, aber die Anforderung wirkt sich auf den Status der Ressource aus. Verwenden Sie die DELETE Methode, um eine HTTP-Anforderung HttpClient für eine Uri Instanz und ein HttpClient.DeleteAsync Objekt zu erstellen:

static async Task DeleteAsync(HttpClient httpClient)
{
    using HttpResponseMessage response = await httpClient.DeleteAsync("todos/1");
    
    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();

    var jsonResponse = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"{jsonResponse}\n");

    // Expected output
    //   DELETE https://jsonplaceholder.typicode.com/todos/1 HTTP/1.1
    //   {}
}

Der Code schließt die folgenden Aufgaben ab:

  • Stellen Sie eine DELETE Anforderung an den "https://jsonplaceholder.typicode.com/todos/1" Endpunkt vor.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails in die Konsole.

Tipp

Die Antwort auf eine DELETE Anfrage (genau wie eine PUT Anfrage) kann einen Inhalt enthalten oder nicht.

Erkunden der HTTP HEAD-Anforderung

Die HEAD-Anforderung ähnelt einer GET-Anforderung. Statt die Ressource zurückzugeben, gibt diese Anforderung nur die Header zurück, die der Ressource zugeordnet sind. Eine Antwort auf eine HEAD-Anforderung gibt keinen Text zurück. Um eine HTTP HEAD-Anfrage mit einer HttpClient-Instanz und einem Uri-Objekt zu stellen, verwenden Sie die Methode HttpClient.SendAsync, wobei der HttpMethod-Typ auf HttpMethod.Head festgelegt wird:

static async Task HeadAsync(HttpClient httpClient)
{
    using HttpRequestMessage request = new(
        HttpMethod.Head, 
        "https://www.example.com");

    using HttpResponseMessage response = await httpClient.SendAsync(request);

    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();

    foreach (var header in response.Headers)
    {
        Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
    }
    Console.WriteLine();

    // Expected output:
    //   HEAD https://www.example.com/ HTTP/1.1
    //   Accept-Ranges: bytes
    //   Age: 550374
    //   Cache-Control: max-age=604800
    //   Date: Wed, 10 Aug 2022 17:24:55 GMT
    //   ETag: "3147526947"
    //   Server: ECS, (cha / 80E2)
    //   X-Cache: HIT
}

Der Code schließt die folgenden Aufgaben ab:

  • Stellen Sie eine HEAD Anforderung an den "https://www.example.com/" Endpunkt vor.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails in die Konsole.
  • Iterieren Sie über alle Antwortheader und schreiben Sie jeden Header in die Konsole.

Erkunden der HTTP-OPTIONS-Anforderung

Mithilfe der OPTIONS-Anforderung wird festgestellt, welche HTTP-Methoden ein Server oder Endpunkt unterstützt. Um eine HTTP OPTIONS-Anfrage mit einer HttpClient-Instanz und einem Uri-Objekt zu stellen, verwenden Sie die Methode HttpClient.SendAsync, wobei der HttpMethod-Typ auf HttpMethod.Options festgelegt wird:

static async Task OptionsAsync(HttpClient httpClient)
{
    using HttpRequestMessage request = new(
        HttpMethod.Options, 
        "https://www.example.com");

    using HttpResponseMessage response = await httpClient.SendAsync(request);

    response.EnsureSuccessStatusCode()
        .WriteRequestToConsole();

    foreach (var header in response.Content.Headers)
    {
        Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
    }
    Console.WriteLine();

    // Expected output
    //   OPTIONS https://www.example.com/ HTTP/1.1
    //   Allow: OPTIONS, GET, HEAD, POST
    //   Content-Type: text/html; charset=utf-8
    //   Expires: Wed, 17 Aug 2022 17:28:42 GMT
    //   Content-Length: 0
}

Der Code schließt die folgenden Aufgaben ab:

  • Senden Sie eine OPTIONS HTTP-Anforderung an den "https://www.example.com/" Endpunkt.
  • Stellen Sie sicher, dass die Antwort erfolgreich ist, und schreiben Sie die Anforderungsdetails in die Konsole.
  • Iterieren Sie über alle Antwortinhaltsheader; schreiben Sie jeden Header in die Konsole.

Entdecken Sie die HTTP TRACE-Anfrage

Die TRACE-Anforderung kann für das Debuggen nützlich sein, da sie ein Loopback der Anforderungsnachricht auf Anwendungsebene bietet. Um eine HTTP-Anforderung TRACE zu erstellen, erstellen Sie eine HttpRequestMessage mithilfe des HttpMethod.Trace Typs:

using HttpRequestMessage request = new(
    HttpMethod.Trace, 
    "{ValidRequestUri}");

Achtung

Nicht alle HTTP-Server unterstützen die TRACE HTTP-Methode. Diese Methode kann eine Sicherheitslücke offenlegen, wenn sie unweise verwendet wird. Weitere Informationen finden Sie unter Open Web Application Security Project (OWASP): Cross Site Tracing.

Verarbeiten einer HTTP-Antwort

Wenn Sie eine HTTP-Antwort behandeln, interagieren Sie mit dem HttpResponseMessage Typ. Um die Gültigkeit einer Antwort zu bewerten, werden mehrere Mitglieder verwendet. Der HTTP-Statuscode ist in der HttpResponseMessage.StatusCode Eigenschaft verfügbar.

Angenommen, Sie senden eine Anfrage unter Verwendung einer Client-Instanz:

using HttpResponseMessage response = await httpClient.SendAsync(request);

Um sicherzustellen, dass der response Wert ist OK (HTTP-Statuscode 200), können Sie den Wert auswerten, wie im folgenden Beispiel gezeigt:

if (response is { StatusCode: HttpStatusCode.OK })
{
    // Omitted for brevity...
}

Es gibt zusätzliche HTTP-Statuscodes, die eine erfolgreiche Antwort repräsentieren, z. B. CREATED (HTTP-Statuscode 201), ACCEPTED (HTTP-Statuscode 202), NO CONTENT (HTTP-Statuscode 204) und RESET CONTENT (HTTP-Statuscode 205). Sie können auch die Eigenschaft HttpResponseMessage.IsSuccessStatusCode verwenden, um diese Codes auszuwerten. Auf diese Weise wird sichergestellt, dass der Antwortstatuscode im Bereich 200–299 liegt:

if (response.IsSuccessStatusCode)
{
    // Omitted for brevity...
}

Wenn das Framework den HttpRequestException Fehler auslösen muss, können Sie die HttpResponseMessage.EnsureSuccessStatusCode() Methode aufrufen:

response.EnsureSuccessStatusCode();

Dieser Code löst einen HttpRequestException Fehler aus, wenn der Antwortstatuscode nicht innerhalb des Bereichs 200-299 liegt.

Erkunden Sie gültige HTTP-Inhaltsantworten

Mit einer gültigen Antwort können Sie mithilfe der Content Eigenschaft auf den Antworttext zugreifen. Der Textkörper ist als HttpContent Instanz verfügbar, mit der Sie als Datenstrom, Bytearray oder Zeichenfolge auf den Textkörper zugreifen können.

Der folgende Code verwendet das responseStream Objekt zum Lesen des Antworttexts:

await using Stream responseStream =
    await response.Content.ReadAsStreamAsync();

Sie können verschiedene Objekte verwenden, um den Antworttext zu lesen. Verwenden Sie das responseByteArray Objekt, um den Antworttext zu lesen:

byte[] responseByteArray = await response.Content.ReadAsByteArrayAsync();

Verwenden Sie das responseString Objekt, um den Antworttext zu lesen:

string responseString = await response.Content.ReadAsStringAsync();

Wenn Sie wissen, dass ein HTTP-Endpunkt JSON zurückgibt, können Sie den Antworttext in ein beliebiges gültiges C#-Objekt unter Verwendung des NuGet-Pakets "System.Net.Http.Json " deserialisieren:

T? result = await response.Content.ReadFromJsonAsync<T>();

Im diesem Code entspricht der result-Wert dem als Typ T deserialisierten Antworttext.

Verwenden der HTTP-Fehlerbehandlung

Wenn eine HTTP-Anforderung fehlschlägt, löst das System das HttpRequestException Objekt aus. Das Abfangen der Ausnahme allein reicht möglicherweise nicht aus. Es gibt andere potenzielle Ausnahmen, die Sie möglicherweise in Betracht ziehen möchten. Der aufrufende Code könnte beispielsweise ein Abbruchtoken verwenden, das vor Abschluss der Anforderung storniert wurde. In diesem Szenario können Sie den TaskCanceledException Fehler abfangen:

using var cts = new CancellationTokenSource();
try
{
    // Assuming:
    //   httpClient.Timeout = TimeSpan.FromSeconds(10)

    using var response = await httpClient.GetAsync(
        "http://localhost:5001/sleepFor?seconds=100", cts.Token);
}
catch (OperationCanceledException ex) when (cts.IsCancellationRequested)
{
    // When the token has been canceled, it is not a timeout.
    Console.WriteLine($"Canceled: {ex.Message}");
}

Wenn Sie eine HTTP-Anforderung vornehmen, wird die gleiche Ausnahme ausgelöst, wenn der Server nicht reagiert, bevor der HttpClient.Timeout Wert überschritten wird. In diesem Szenario können Sie jedoch das Auftreten der Zeitüberschreitung erkennen, indem Sie beim Auswerten der Exception.InnerException-Eigenschaft den Fehler TaskCanceledException abrufen:

try
{
    // Assuming:
    //   httpClient.Timeout = TimeSpan.FromSeconds(10)

    using var response = await httpClient.GetAsync(
        "http://localhost:5001/sleepFor?seconds=100");
}
catch (OperationCanceledException ex) when (ex.InnerException is TimeoutException tex)
{
    Console.WriteLine($"Timed out: {ex.Message}, {tex.Message}");
}

Wenn es sich bei der inneren Ausnahme im Code um einen TimeoutException-Typ handelt, dann ist der Timeout aufgetreten, und das Abbruchtoken bricht die Anforderung nicht ab.

Um den HTTP-Statuscode auszuwerten, wenn Sie das HttpRequestException Objekt abfangen, können Sie die HttpRequestException.StatusCode Eigenschaft auswerten:

try
{
    // Assuming:
    //   httpClient.Timeout = TimeSpan.FromSeconds(10)

    using var response = await httpClient.GetAsync(
        "http://localhost:5001/doesNotExist");

    response.EnsureSuccessStatusCode();
}
catch (HttpRequestException ex) when (ex is { StatusCode: HttpStatusCode.NotFound })
{
    // Handle 404
    Console.WriteLine($"Not found: {ex.Message}");
}

Im Code wird die EnsureSuccessStatusCode() Methode aufgerufen, um eine Ausnahme auszuwerfen, wenn die Antwort nicht erfolgreich ist. Anschließend wird die Eigenschaft HttpRequestException.StatusCode ausgewertet, um festzustellen, ob es sich um eine 404-Antwort handelt (HTTP-Statuscode 404). Es gibt mehrere Hilfsmethoden für das HttpClient Objekt, die die EnsureSuccessStatusCode Methode in Ihrem Auftrag implizit aufrufen.

Berücksichtigen Sie bei der HTTP-Fehlerbehandlung die folgenden APIs:

Tipp

Alle HttpClient Methoden, die verwendet werden, um HTTP-Anforderungen auszuführen, die keinen HttpResponseMessage Typ implizit aufrufen, rufen die EnsureSuccessStatusCode Methode in Ihrem Auftrag auf.

Wenn Sie diese Methoden aufrufen, können Sie das HttpRequestException Objekt behandeln und die HttpRequestException.StatusCode Eigenschaft auswerten, um den HTTP-Statuscode der Antwort zu ermitteln:

try
{
    // These extension methods will throw HttpRequestException
    // with StatusCode set when the HTTP request status code isn't 2xx:
    //
    //   GetByteArrayAsync
    //   GetStreamAsync
    //   GetStringAsync

    using var stream = await httpClient.GetStreamAsync(
        "https://localhost:5001/doesNotExists");
}
catch (HttpRequestException ex) when (ex is { StatusCode: HttpStatusCode.NotFound })
{
    // Handle 404
    Console.WriteLine($"Not found: {ex.Message}");
}

Es kann Szenarien geben, in denen Sie das HttpRequestException Objekt in Ihrem Code auslösen müssen. Der HttpRequestException() Konstruktor ist öffentlich, und Sie können ihn verwenden, um eine Ausnahme mit einer benutzerdefinierten Nachricht auszuwerfen:

try
{
    using var response = await httpClient.GetAsync(
        "https://localhost:5001/doesNotExists");

    // Throw for anything higher than 400.
    if (response is { StatusCode: >= HttpStatusCode.BadRequest })
    {
        throw new HttpRequestException(
            "Something went wrong", inner: null, response.StatusCode);
    }
}
catch (HttpRequestException ex) when (ex is { StatusCode: HttpStatusCode.NotFound })
{
    Console.WriteLine($"Not found: {ex.Message}");
}

Konfigurieren eines HTTP-Proxys

Ein HTTP-Proxy kann auf zwei Arten konfiguriert werden. Für die Eigenschaft HttpClient.DefaultProxy wird ein Standardwert festgelegt. Alternativ können Sie einen Proxy für die Eigenschaft HttpClientHandler.Proxy angeben.

Verwenden eines globalen Standardproxys

Die HttpClient.DefaultProxy Eigenschaft ist eine statische Eigenschaft, die den Standardproxy bestimmt, den alle HttpClient Instanzen verwenden, wenn kein Proxy explizit im HttpClientHandler Objekt festgelegt wird, das über den Konstruktor übergeben wird.

Die von dieser Eigenschaft zurückgegebene Standardinstanz wird abhängig von Ihrer Plattform gemäß einem anderen Satz von Regeln initialisiert.

  • Windows: Lesen Sie die Proxykonfiguration aus den Umgebungsvariablen, oder wenn diese nicht definiert sind, lesen Sie die Einstellungen aus den Benutzerproxyeinstellungen.
  • macOS: Lesen Sie die Proxy-Konfiguration aus den Umgebungsvariablen oder, wenn keine Variablen definiert sind, aus den System-Proxy-Einstellungen.
  • Linux: Lesen Sie die Proxy-Konfiguration aus den Umgebungsvariablen oder, falls keine Variablen definiert sind, initialisieren Sie eine nicht konfigurierte Instanz, um alle Adressen zu umgehen.

Die DefaultProxy Eigenschaftsinitialisierung auf Windows- und Unix-basierten Plattformen verwendet die folgenden Umgebungsvariablen:

  • HTTP_PROXY: Der proxyserver, der für HTTP-Anforderungen verwendet wird.
  • HTTPS_PROXY: Der proxyserver, der für HTTPS-Anforderungen verwendet wird.
  • ALL_PROXY: Der Proxyserver, der für HTTP- und/oder HTTPS-Anforderungen verwendet wird, wenn die HTTP_PROXY Und/oder HTTPS_PROXY Variablen nicht definiert sind.
  • NO_PROXY: Eine durch Trennzeichen getrennte Liste von Hostnamen, die von der Proxyerstellung ausgeschlossen werden sollen. Sternchen werden für Wildcards nicht unterstützt. Verwenden Sie einen führenden Punkt (.), wenn Sie einer Unterdomäne entsprechen möchten. Beispiele: NO_PROXY=.example.com (mit vorangestelltem Punkt) entspricht www.example.com, stimmt aber nicht mit example.com überein. NO_PROXY=example.com (ohne führenden Punkt) stimmt nicht mit www.example.com überein. Dieses Verhalten könnte in Zukunft überarbeitet werden, um anderen Ökosystemen besser zu entsprechen.

Bei Systemen, bei denen bei Umgebungsvariablen die Groß-/Kleinschreibung beachtet wird, bestehen die Variablennamen unter Umständen nur aus Kleinbuchstaben oder nur aus Großbuchstaben. Die Namen in Kleinbuchstaben werden zuerst überprüft.

Der Proxyserver kann ein Hostname oder eine IP-Adresse sein, optional gefolgt von einem Doppelpunkt und einer Portnummer, oder es kann sich um eine http URL handeln, optional einschließlich eines Benutzernamens und Kennworts für die Proxyauthentifizierung. Die URL muss mit http, nicht https, beginnen und darf keinen Text nach dem Hostnamen, der IP oder dem Port enthalten.

Konfigurieren des Proxys pro Client

Die HttpClientHandler.Proxy Eigenschaft identifiziert das WebProxy Objekt, das zum Verarbeiten von Anforderungen an Internetressourcen verwendet werden soll. Um anzugeben, dass kein Proxy verwendet werden soll, legen Sie die Eigenschaft Proxy auf die Proxyinstanz fest, die von der Methode GlobalProxySelection.GetEmptyWebProxy() zurückgegeben wird.

Die Lokale Computer- oder Anwendungskonfigurationsdatei kann angeben, dass ein Standardproxy verwendet wird. Wenn die Proxy Eigenschaft angegeben ist, überschreiben die Proxyeinstellungen aus der Proxy Eigenschaft die lokale Computer- oder Anwendungskonfigurationsdatei, und der Handler verwendet die angegebenen Proxyeinstellungen. Wenn in einer Konfigurationsdatei kein Proxy angegeben ist und die Proxy Eigenschaft nicht angegeben ist, verwendet der Handler die vom lokalen Computer geerbten Proxyeinstellungen. Wenn keine Proxyeinstellungen vorhanden sind, wird die Anforderung direkt an den Server gesendet.

Die Klasse HttpClientHandler analysiert eine Proxyumgehungsliste mit Platzhaltern, die von den lokalen Computereinstellungen übernommen wurden. Beispielsweise analysiert die Klasse HttpClientHandler eine Umgehungsliste "nt*" aus Browsern als regulären Ausdruck von "nt.*". Daher wird eine URL von http://nt.com mithilfe der HttpClientHandler Klasse am Proxy vorbeigeführt.

Die HttpClientHandler-Klasse unterstützt die lokale Proxyumgehung. Die Klasse betrachtet ein Ziel als lokal, wenn eine der folgenden Bedingungen erfüllt ist:

  • Das Ziel enthält einen flachen Namen (keine Punkte (.) in der URL).
  • Das Ziel enthält eine Loopbackadresse (Loopback oder IPv6Loopback) oder das Ziel enthält eine IPAddress Eigenschaft, die dem lokalen Computer zugewiesen ist.
  • Das Domänensuffix des Ziels entspricht dem Domänensuffix des lokalen Computers, wie in der DomainName Eigenschaft definiert.

Weitere Informationen zum Konfigurieren eines Proxys finden Sie in den folgenden APIs:

Nächste Schritte