HTTP-aanvragen maken met de HttpClient-klasse
In dit artikel leert u hoe u HTTP-aanvragen maakt en antwoorden verwerkt met de HttpClient
-klasse.
Belangrijk
Alle voorbeeld-HTTP-aanvragen in dit artikel zijn gericht op een van de volgende URL's:
- https://jsonplaceholder.typicode.com: een site die een gratis nep-API-platform biedt voor testen en prototypen.
- https://www.example.com: een domein dat beschikbaar is voor gebruik in illustratieve voorbeelden in documenten.
HTTP-eindpunten retourneren doorgaans JSON-gegevens (JavaScript Object Notation), maar niet altijd. Voor het gemak biedt het optionele System.Net.Http.Json NuGet-pakket verschillende uitbreidingsmethoden voor HttpClient
en HttpContent
objecten die automatische serialisatie en deserialisatie uitvoeren met behulp van het 📦 System.Text.Json- NuGet-pakket. In de voorbeelden in dit artikel wordt aandacht besteed aan plaatsen waar deze extensies beschikbaar zijn.
Tip
Alle broncode waarnaar in dit artikel wordt verwezen, is beschikbaar in de GitHub: .NET Docs opslagplaats.
Een HttpClient-object maken
De meeste voorbeelden in dit artikel gebruiken hetzelfde HttpClient
exemplaar, zodat u het exemplaar één keer kunt configureren en deze kunt gebruiken voor de resterende voorbeelden. Als u een HttpClient
-object wilt maken, gebruikt u de HttpClient
klasseconstructor. Zie Richtlijnen voor het gebruik van HttpClient voor meer informatie.
// 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"),
};
De code voltooit de volgende taken:
- Instantieer een nieuw
HttpClient
exemplaar als eenstatic
variabele. Volgens de richtlijnen, is de aanbevolen aanpak omHttpClient
exemplaren tijdens de levenscyclus van de toepassing opnieuw te gebruiken. - Stel de eigenschap HttpClient.BaseAddress in op
"https://jsonplaceholder.typicode.com"
.
In dit HttpClient
exemplaar wordt het basisadres gebruikt om volgende aanvragen te doen. Als u andere configuraties wilt toepassen, kunt u de volgende API's overwegen:
- Stel de eigenschap HttpClient.DefaultRequestHeaders in.
- Pas een niet-standaard HttpClient.Timeout eigenschap toe.
- Geef de eigenschap HttpClient.DefaultRequestVersion op.
Tip
U kunt ook HttpClient
exemplaren maken met behulp van een factory-patroonbenadering waarmee u een willekeurig aantal clients kunt configureren en als afhankelijkheidsinjectieservices kunt gebruiken. Zie HTTP-clientfabriek met .NET voor meer informatie.
Een HTTP-aanvraag maken
Als u een HTTP-aanvraag wilt maken, roept u een van de volgende API-methoden aan:
HTTP-methode | 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 |
†Een
USER SPECIFIED
-aanvraag geeft aan dat deSendAsync
-methode elk geldig HttpMethod-object accepteert.
Waarschuwing
Het maken van HTTP-aanvragen wordt beschouwd als netwerk-I/O-gebonden werk. Er bestaat een synchrone HttpClient.Send methode, maar u wordt aangeraden in plaats daarvan de asynchrone API's te gebruiken, tenzij u een goede reden hebt om dat niet te doen.
Notitie
Bij het richten op Android-apparaten (zoals bij .NET MAUI-ontwikkeling), moet u de android:usesCleartextTraffic="true"
-definitie toevoegen aan de <application></application>
-sectie in het AndroidManifest.xml-bestand. Met deze instelling wordt onversleuteld verkeer, zoals HTTP-aanvragen, ingeschakeld, dat anders standaard wordt uitgeschakeld vanwege Android-beveiligingsbeleidEN. Bekijk de volgende voorbeeld-XML-instellingen:
<?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>
Zie Clear Text-netwerkverkeer inschakelen voor het localhost-domein voor meer informatie.
HTTP-inhoud begrijpen
Het HttpContent type wordt gebruikt om een hoofdtekst van een HTTP-entiteit en bijbehorende inhoudsheaders weer te geven. Voor HTTP-methoden (of aanvraagmethoden) waarvoor een hoofdtekst (POST
, PUT
, PATCH
) is vereist, gebruikt u de HttpContent-klasse om de hoofdtekst van de aanvraag op te geven. De meeste voorbeelden laten zien hoe u de StringContent subklasse voorbereidt met een JSON-nettolading, maar andere subklassen bestaan voor verschillende typen inhoud (MIME).
- ByteArrayContent: Biedt HTTP-inhoud op basis van een bytematrix.
-
FormUrlEncodedContent: biedt HTTP-inhoud voor tuples met naam/waarde die zijn gecodeerd met behulp van het
"application/x-www-form-urlencoded"
MIME-type. - JsonContent: Biedt HTTP-inhoud op basis van JSON.
-
MultipartContent: Biedt een verzameling HttpContent-objecten die worden geserialiseerd met behulp van de specificatie van het
"multipart/*"
MIME-type. -
MultipartFormDataContent: biedt een container voor inhoud die is gecodeerd met behulp van het
"multipart/form-data"
MIME-type. - ReadOnlyMemoryContent: biedt HTTP-inhoud op basis van een ReadOnlyMemory<T> waarde.
- StreamContent: Biedt HTTP-inhoud op basis van een stream.
- StringContent: Biedt HTTP-inhoud op basis van een tekenreeks.
De HttpContent
-klasse wordt ook gebruikt om de antwoordtekst van de HttpResponseMessage-klasse weer te geven, die toegankelijk is voor de eigenschap HttpResponseMessage.Content.
Een HTTP GET-aanvraag gebruiken
Een GET
verzoek mag geen inhoud verzenden. Deze aanvraag wordt gebruikt (zoals de methodenaam aangeeft) om gegevens op te halen (of op te halen) uit een resource. Als u een HTTP-GET
-aanvraag wilt indienen op basis van een HttpClient
-exemplaar en een Uri-object, gebruikt u de methode HttpClient.GetAsync:
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
// }
}
De code voltooit de volgende taken:
- Een
GET
aanvraag indienen bij het"https://jsonplaceholder.typicode.com/todos/3"
-eindpunt. - Zorg ervoor dat de respons succesvol is.
- Schrijf de aanvraagdetails naar de console.
- Lees de hoofdtekst van het antwoord als een tekenreeks.
- Schrijf de hoofdtekst van het JSON-antwoord naar de console.
De methode WriteRequestToConsole
is een aangepaste extensie die geen deel uitmaakt van het framework. Als u nieuwsgierig bent naar de implementatie, kunt u de volgende C#-code overwegen:
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}");
}
}
Deze functionaliteit wordt gebruikt om de aanvraaggegevens naar de console te schrijven in het volgende formulier:
<HTTP Request Method> <Request URI> <HTTP/Version>
Als voorbeeld voert de GET
aanvraag voor het "https://jsonplaceholder.typicode.com/todos/3"
-eindpunt het volgende bericht uit:
GET https://jsonplaceholder.typicode.com/todos/3 HTTP/1.1
De HTTP GET-aanvraag maken vanuit JSON
Het https://jsonplaceholder.typicode.com/todos-eindpunt retourneert een JSON-matrix van Todo
objecten. De JSON-structuur lijkt op de volgende vorm:
[
{
"userId": 1,
"id": 1,
"title": "example title",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "another example title",
"completed": true
},
]
Het C# Todo
-object wordt als volgt gedefinieerd:
public record class Todo(
int? UserId = null,
int? Id = null,
string? Title = null,
bool? Completed = null);
Het is een record class
type, met optionele Id
, Title
en Completed
eigenschappen UserId
. Zie record
voor meer informatie over het type. Als u GET
aanvragen automatisch wilt deserialiseren in een sterk getypeerd C#-object, gebruikt u de GetFromJsonAsync extensiemethode die deel uitmaakt van het 📦 System.Net.Http.Json- NuGet-pakket.
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 }
}
De code voltooit de volgende taken:
Dien een
GET
-aanvraag in bij"https://jsonplaceholder.typicode.com/todos?userId=1&completed=false"
.De querytekenreeks vertegenwoordigt de filtercriteria voor de aanvraag. Wanneer de opdracht slaagt, wordt het antwoord automatisch gedeserialiseerd in een
List<Todo>
-object.Schrijf de aanvraagdetails naar de console, samen met elk
Todo
-object.
Een HTTP POST-aanvraag gebruiken
Een POST
aanvraag verzendt gegevens naar de server voor verwerking. De Content-Type
header van de aanvraag geeft aan welk MIME-type de hoofdtekst verzendt. Als u een HTTP-POST
-aanvraag wilt indienen op basis van een HttpClient
-exemplaar en een Uri-object, gebruikt u de methode HttpClient.PostAsync:
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
// }
}
De code voltooit de volgende taken:
- Bereid een StringContent-exemplaar voor met de JSON-hoofdtekst van de aanvraag (MIME-type van
"application/json"
). - Een
POST
aanvraag indienen bij het"https://jsonplaceholder.typicode.com/todos"
-eindpunt. - Zorg ervoor dat het antwoord succesvol is en log de aanvraagdetails naar de console.
- Schrijf de hoofdtekst van het antwoord als een tekenreeks naar de console.
De HTTP POST-aanvraag maken als JSON
Als u aanvraagargumenten automatisch wilt serialiseren POST
en antwoorden wilt deserialiseren in sterk getypte C#-objecten, gebruikt u de PostAsJsonAsync extensiemethode die deel uitmaakt van het NuGet-pakket System.Net.Http.Json .
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 }
}
De code voltooit de volgende taken:
- Serialiseer het
Todo
-exemplaar als JSON en dien eenPOST
aanvraag in bij het"https://jsonplaceholder.typicode.com/todos"
-eindpunt. - Zorg ervoor dat de respons succesvol is en schrijf de details van de aanvraag naar de console.
- Deserialiseer de response body in een
Todo
-exemplaar en schrijf hetTodo
-object naar de console.
Een HTTP PUT-aanvraag gebruiken
De PUT
verzoekmethode vervangt een bestaande resource of creëert een nieuwe met behulp van de inhoud van de aanvraagbody. Als u een HTTP-PUT
-aanvraag wilt indienen op basis van een HttpClient
-exemplaar en een Uri-object, gebruikt u de methode HttpClient.PutAsync:
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
// }
}
De code voltooit de volgende taken:
- Bereid een StringContent-exemplaar voor met de JSON-hoofdtekst van de aanvraag (MIME-type van
"application/json"
). - Een
PUT
aanvraag indienen bij het"https://jsonplaceholder.typicode.com/todos/1"
-eindpunt. - Zorg ervoor dat het antwoord is geslaagd en schrijf de aanvraagdetails met de hoofdtekst van het JSON-antwoord naar de console.
De HTTP PUT-aanvraag maken als JSON
Als u aanvraagargumenten automatisch wilt serialiseren PUT
en antwoorden wilt deserialiseren in sterk getypte C#-objecten, gebruikt u de PutAsJsonAsync extensiemethode die deel uitmaakt van het NuGet-pakket System.Net.Http.Json .
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 }
}
De code voltooit de volgende taken:
- Serialiseer het
Todo
-exemplaar als JSON en dien eenPUT
aanvraag in bij het"https://jsonplaceholder.typicode.com/todos/5"
-eindpunt. - Zorg ervoor dat het antwoord succesvol is en schrijf de aanvraagdetails naar de console.
- Deserialiseer de antwoordinhoud in een
Todo
exemplaar en schrijf deTodo
objecten op de console.
Een HTTP PATCH-aanvraag gebruiken
De PATCH
aanvraag is een gedeeltelijke update van een bestaande resource. Deze aanvraag maakt geen nieuwe resource en is niet bedoeld om een bestaande resource te vervangen. In plaats daarvan werkt deze methode slechts gedeeltelijk een resource bij. Als u een HTTP-PATCH
-aanvraag wilt indienen op basis van een HttpClient
-exemplaar en een Uri-object, gebruikt u de methode HttpClient.PatchAsync:
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
// }
}
De code voltooit de volgende taken:
- Bereid een StringContent-exemplaar voor met de JSON-hoofdtekst van de aanvraag (MIME-type van
"application/json"
). - Een
PATCH
aanvraag indienen bij het"https://jsonplaceholder.typicode.com/todos/1"
-eindpunt. - Zorg ervoor dat het antwoord is geslaagd en schrijf de aanvraagdetails met de hoofdtekst van het JSON-antwoord naar de console.
Er bestaan geen uitbreidingsmethoden voor PATCH
aanvragen in het System.Net.Http.Json
NuGet-pakket.
Een HTTP DELETE-aanvraag gebruiken
Een DELETE
verzoek verwijdert een bestaande resource en het verzoek is idempotent, maar niet veilig. Meerdere DELETE
aanvragen voor dezelfde resources opleveren hetzelfde resultaat, maar de aanvraag is van invloed op de status van de resource. Als u een HTTP-DELETE
-aanvraag wilt indienen op basis van een HttpClient
-exemplaar en een Uri-object, gebruikt u de methode HttpClient.DeleteAsync:
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
// {}
}
De code voltooit de volgende taken:
- Een
DELETE
aanvraag indienen bij het"https://jsonplaceholder.typicode.com/todos/1"
-eindpunt. - Zorg ervoor dat de respons succesvol is en schrijf de verzoekdetails naar de console.
Tip
Het antwoord op een DELETE
aanvraag (net als een PUT
aanvraag) kan wel of geen inhoud bevatten.
De HTTP HEAD-aanvraag verkennen
De HEAD
aanvraag is vergelijkbaar met een GET
aanvraag. In plaats van de resource te retourneren, retourneert deze aanvraag alleen de headers die aan de resource zijn gekoppeld. Een antwoord op het HEAD
verzoek retourneert geen inhoud. Als u een HTTP-HEAD
-aanvraag wilt indienen op basis van een HttpClient
exemplaar en een Uri-object, gebruikt u de methode HttpClient.SendAsync met het HttpMethod type ingesteld op HttpMethod.Head
:
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
}
De code voltooit de volgende taken:
- Een
HEAD
aanvraag indienen bij het"https://www.example.com/"
-eindpunt. - Zorg ervoor dat de reactie succesvol is en log de aanvraagdetails naar de console.
- Itereer over alle antwoordheaders en schrijf elke header naar de console.
De HTTP OPTIONS-aanvraag verkennen
De OPTIONS
aanvraag wordt gebruikt om te bepalen welke HTTP-methoden een server of eindpunt ondersteunt. Als u een HTTP-OPTIONS
-aanvraag wilt indienen op basis van een HttpClient
exemplaar en een Uri-object, gebruikt u de methode HttpClient.SendAsync met het HttpMethod type ingesteld op HttpMethod.Options
:
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
}
De code voltooit de volgende taken:
- Verzend een
OPTIONS
HTTP-aanvraag naar het"https://www.example.com/"
-eindpunt. - Zorg dat de reactie succesvol is en schrijf de aanvraagdetails naar de console.
- Itereer over alle headers van de antwoordinhoud en schrijf elke header naar de console.
De HTTP TRACE-aanvraag verkennen
De TRACE
aanvraag kan handig zijn voor foutopsporing, omdat deze een terugkoppeling op toepassingsniveau van het aanvraagbericht biedt. Als u een HTTP-TRACE
-aanvraag wilt maken, maakt u een HttpRequestMessage met behulp van het HttpMethod.Trace
type:
using HttpRequestMessage request = new(
HttpMethod.Trace,
"{ValidRequestUri}");
Let op
Niet alle HTTP-servers ondersteunen de TRACE
HTTP-methode. Deze methode kan een beveiligingsprobleem blootstellen als deze onwijze wordt gebruikt. Voor meer informatie, zie Open Web Application Security Project (OWASP): Cross Site Tracing.
Een HTTP-antwoord verwerken
Wanneer u een HTTP-antwoord verwerkt, communiceert u met het HttpResponseMessage type. Verschillende leden worden gebruikt om de geldigheid van een antwoord te evalueren. De HTTP-statuscode is beschikbaar in de eigenschap HttpResponseMessage.StatusCode.
Stel je voor dat je een aanvraag verstuurt met een clientinstantie:
using HttpResponseMessage response = await httpClient.SendAsync(request);
Om ervoor te zorgen dat de response
is OK
(HTTP-statuscode 200), kunt u de waarde evalueren zoals wordt weergegeven in het volgende voorbeeld:
if (response is { StatusCode: HttpStatusCode.OK })
{
// Omitted for brevity...
}
Er zijn andere HTTP-statuscodes die een geslaagd antwoord vertegenwoordigen, zoals CREATED
(HTTP-statuscode 201), ACCEPTED
(HTTP-statuscode 202), NO CONTENT
(HTTP-statuscode 204) en RESET CONTENT
(HTTP-statuscode 205). U kunt de HttpResponseMessage.IsSuccessStatusCode eigenschap ook gebruiken om deze codes te evalueren, waardoor de antwoordstatuscode binnen het bereik 200-299 valt:
if (response.IsSuccessStatusCode)
{
// Omitted for brevity...
}
Als u het framework de HttpRequestException-fout moet laten veroorzaken, kunt u de methode HttpResponseMessage.EnsureSuccessStatusCode() aanroepen:
response.EnsureSuccessStatusCode();
Deze code genereert een HttpRequestException
-fout als de antwoordstatuscode zich niet binnen het bereik van 200-299 bevindt.
Http-geldige inhoudsreacties verkennen
Met een geldig antwoord hebt u toegang tot de hoofdtekst van het antwoord met behulp van de eigenschap Content. De hoofdtekst is beschikbaar als een HttpContent exemplaar, dat u kunt gebruiken om toegang te krijgen tot de hoofdtekst als een stroom, bytematrix of tekenreeks.
In de volgende code wordt het responseStream
-object gebruikt om de hoofdtekst van het antwoord te lezen:
await using Stream responseStream =
await response.Content.ReadAsStreamAsync();
U kunt verschillende objecten gebruiken om de hoofdtekst van het antwoord te lezen. Gebruik het responseByteArray
-object om de hoofdtekst van het antwoord te lezen:
byte[] responseByteArray = await response.Content.ReadAsByteArrayAsync();
Gebruik het responseString
-object om de hoofdtekst van het antwoord te lezen:
string responseString = await response.Content.ReadAsStringAsync();
Wanneer u weet dat een HTTP-eindpunt JSON retourneert, kunt u de hoofdtekst van het antwoord deserialiseren in een geldig C#-object met behulp van het System.Net.Http.Json-pakket NuGet:
T? result = await response.Content.ReadFromJsonAsync<T>();
In deze code is de result
waarde de antwoordtekst gedeserialiseerd als het type T
.
HTTP-foutafhandeling gebruiken
Wanneer een HTTP-aanvraag mislukt, genereert het systeem het HttpRequestException-object. Het is mogelijk dat het niet voldoende is om alleen de uitzondering te ondervangen. Er zijn andere mogelijke uitzonderingen die u zou kunnen overwegen te behandelen. De aanroepende code kan bijvoorbeeld een annuleringstoken gebruiken dat is geannuleerd voordat de aanvraag is voltooid. In dit scenario kunt u de TaskCanceledException fout ondervangen:
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}");
}
Wanneer u een HTTP-aanvraag indient en de server niet reageert voordat de HttpClient.Timeout waarde wordt overschreden, wordt dezelfde uitzondering gegenereerd. In dit scenario kunt u onderscheiden dat de time-out is opgetreden door de eigenschap Exception.InnerException te evalueren bij het ondervangen van de TaskCanceledException fout:
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}");
}
Wanneer de interne exceptie van type TimeoutException in de code voorkomt, is de tijdslimiet overschreden en annuleert het annuleringstoken de aanvraag niet.
Als u de HTTP-statuscode wilt evalueren wanneer u het HttpRequestException-object ziet, kunt u de eigenschap HttpRequestException.StatusCode evalueren:
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}");
}
In de code wordt de EnsureSuccessStatusCode() methode aangeroepen om een uitzondering te genereren als het antwoord niet lukt. De HttpRequestException.StatusCode eigenschap wordt vervolgens geëvalueerd om te bepalen of het antwoord een 404
(HTTP-statuscode 404) is. Er zijn verschillende helpermethoden voor het HttpClient
-object waarmee de methode EnsureSuccessStatusCode
impliciet namens u wordt aangeroepen.
Houd rekening met de volgende API's voor het overdragen van HTTP-fouten:
- methode HttpClient.GetByteArrayAsync
- methode HttpClient.GetStreamAsync
- methode HttpClient.GetStringAsync
Tip
Alle HttpClient
methoden die worden gebruikt om HTTP-aanvragen te maken die geen HttpResponseMessage
type retourneren, roepen de EnsureSuccessStatusCode
methode impliciet namens u aan.
Wanneer u deze methoden aanroept, kunt u het HttpRequestException
-object afhandelen en de eigenschap HttpRequestException.StatusCode evalueren om de HTTP-statuscode van het antwoord te bepalen:
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}");
}
Er kunnen scenario's zijn waarin u het HttpRequestException-object in uw code moet gooien. De HttpRequestException() constructor is openbaar en u kunt deze gebruiken om een uitzondering met een aangepast bericht te genereren:
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}");
}
Een HTTP-proxy configureren
Een HTTP-proxy kan op twee manieren worden geconfigureerd. Er wordt een standaardwaarde opgegeven voor de HttpClient.DefaultProxy eigenschap. U kunt ook een proxy opgeven voor de HttpClientHandler.Proxy eigenschap.
Een algemene standaardproxy gebruiken
De eigenschap HttpClient.DefaultProxy
is een statische eigenschap die bepaalt welke standaardproxy alle HttpClient
exemplaren gebruiken, als er geen proxy expliciet is ingesteld in het HttpClientHandler-object dat wordt doorgegeven via de constructor.
Het standaardexemplaren dat door deze eigenschap wordt geretourneerd, wordt geïnitialiseerd volgens een andere set regels, afhankelijk van uw platform:
- Windows: proxyconfiguratie lezen uit omgevingsvariabelen of als variabelen niet zijn gedefinieerd, lezen uit de proxy-instellingen van de gebruiker.
- macOS-: proxyconfiguratie lezen uit omgevingsvariabelen of als er geen variabelen zijn gedefinieerd, lezen uit de systeemproxy-instellingen.
- Linux-: lees proxyconfiguratie uit omgevingsvariabelen, of, als variabelen niet zijn gedefinieerd, initialiseer een niet-geconfigureerd exemplaar om alle adressen te omzeilen.
De DefaultProxy
eigenschap initialisatie op Windows- en Unix-platforms maakt gebruik van de volgende omgevingsvariabelen:
-
HTTP_PROXY
: de proxyserver die wordt gebruikt voor HTTP-aanvragen. -
HTTPS_PROXY
: de proxyserver die wordt gebruikt voor HTTPS-aanvragen. -
ALL_PROXY
: de proxyserver die wordt gebruikt op HTTP- en/of HTTPS-aanvragen wanneer de variabelenHTTP_PROXY
en/ofHTTPS_PROXY
niet zijn gedefinieerd. -
NO_PROXY
: een door komma's gescheiden lijst met hostnamen die moeten worden uitgesloten van proxying. Asterisken worden niet ondersteund voor wildcards. Gebruik een voorloopperiode (.) als u een subdomein wilt vergelijken. Voorbeelden:NO_PROXY=.example.com
(met voorloopperiode) komt overeen metwww.example.com
, maar komt niet overeen metexample.com
.NO_PROXY=example.com
(zonder voorloopperiode) komt niet overeen metwww.example.com
. Dit gedrag kan in de toekomst opnieuw worden bekeken om beter aan te sluiten bij andere ecosystemen.
Op systemen waar omgevingsvariabelen hoofdlettergevoelig zijn, kunnen de variabelennamen volledig in kleine letters of volledig in hoofdletters zijn. De namen in kleine letters worden eerst gecontroleerd.
De proxyserver kan een hostnaam of IP-adres zijn, eventueel gevolgd door een dubbele punt en poortnummer, of kan een http
URL zijn, eventueel een gebruikersnaam en wachtwoord voor proxyverificatie bevatten. De URL moet beginnen met http
, niet https
en mag geen tekst bevatten na de hostnaam, het IP-adres of de poort.
De proxy per client configureren
De eigenschap HttpClientHandler.Proxy identificeert het WebProxy-object dat moet worden gebruikt voor het verwerken van aanvragen voor internetbronnen. Als u wilt opgeven dat er geen proxy moet worden gebruikt, stelt u de Proxy
eigenschap in op het proxy-exemplaar dat door de GlobalProxySelection.GetEmptyWebProxy() methode wordt geretourneerd.
Het configuratiebestand van de lokale computer of toepassing kan opgeven dat er een standaardproxy wordt gebruikt. Als de eigenschap Proxy
is opgegeven, overschrijven de proxy-instellingen van de eigenschap Proxy
het configuratiebestand van de lokale computer of toepassing en gebruikt de handler de opgegeven proxy-instellingen. Als er geen proxy is opgegeven in een configuratiebestand en de eigenschap Proxy
niet is opgegeven, gebruikt de handler de proxy-instellingen die zijn overgenomen van de lokale computer. Als er geen proxy-instellingen zijn, wordt de aanvraag rechtstreeks naar de server verzonden.
De HttpClientHandler klasse parseert een lijst met proxy-bypasss met jokertekens die zijn overgenomen van de lokale computerinstellingen. Bijvoorbeeld, de HttpClientHandler
-klasse parseert een bypass-lijst uit "nt*"
van browsers als een reguliere expressie van "nt.*"
. Daarom wordt met een URL van http://nt.com
de proxy overgeslagen met behulp van de HttpClientHandler
-klasse.
De HttpClientHandler
klasse ondersteunt het omzeilen van lokale proxy's. De klasse beschouwt een bestemming als lokaal wanneer aan een van de volgende voorwaarden wordt voldaan:
- De bestemming bevat een platte naam (geen punten (.) in de URL.
- De bestemming bevat een loopback-adres (Loopback of IPv6Loopback) of de bestemming bevat een IPAddress eigenschap die is toegewezen aan de lokale computer.
- Het domeinachtervoegsel van de bestemming komt overeen met het domeinachtervoegsel van de lokale computer, zoals gedefinieerd in de eigenschap DomainName.
Zie de volgende API's voor meer informatie over het configureren van een proxy:
- eigenschap WebProxy.Address
- eigenschap WebProxy.BypassProxyOnLocal
- eigenschap WebProxy.BypassArrayList