Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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:
- https://jsonplaceholder.typicode.com: Eine Website, die eine kostenlose gefälschte API-Plattform zum Testen und Prototypen bereitstellt.
- https://www.example.com: Eine Domäne, die in illustrativen Beispielen in Dokumenten verwendet werden kann.
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 alsstatic
Variable. Gemäß den Richtlinien wird empfohlen, Instanzen während des Anwendungslebenszyklus wiederzuverwendenHttpClient
. - 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:
- Legen Sie die HttpClient.DefaultRequestHeaders-Eigenschaft fest.
- Anwenden einer nicht standardmäßigen HttpClient.Timeout Eigenschaft.
- Geben Sie die HttpClient.DefaultRequestVersion Eigenschaft an.
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 dieSendAsync
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, PATCH
verwenden 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 einePOST
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 dasTodo
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 einePUT
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 dieTodo
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:
- HttpClient.GetByteArrayAsync-Methode
- HttpClient.GetStreamAsync-Methode
- HttpClient.GetStringAsync-Methode
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 dieHTTP_PROXY
Und/oderHTTPS_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) entsprichtwww.example.com
, stimmt aber nicht mitexample.com
überein.NO_PROXY=example.com
(ohne führenden Punkt) stimmt nicht mitwww.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:
- WebProxy.Address-Eigenschaft
- WebProxy.BypassProxyOnLocal-Eigenschaft
- WebProxy.BypassArrayList-Eigenschaft