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 zijn gericht op een van de volgende URL's:
- https://jsonplaceholder.typicode.com: Gratis nep-API voor testen en prototypen.
- https://www.example.com: Dit domein is bedoeld 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
die automatische serialisatie en deserialisatie uitvoeren met behulp van System.Text.Json
. De voorbeelden die volgen, roepen aandacht op plaatsen waar deze extensies beschikbaar zijn.
Tip
Alle broncode uit dit artikel is beschikbaar in de GitHub: .NET Docs-opslagplaats .
Een HttpClient
De meeste van de volgende voorbeelden gebruiken hetzelfde HttpClient
exemplaar opnieuw en hoeven daarom slechts eenmaal te worden geconfigureerd. Gebruik de HttpClient
klasseconstructor om een HttpClient
te maken. 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"),
};
Met de voorgaande code wordt:
- Instantieert een nieuw
HttpClient
exemplaar als eenstatic
variabele. Volgens de richtlijnen is het raadzaam om instanties opnieuw te gebruikenHttpClient
tijdens de levenscyclus van de toepassing. - Hiermee stelt u het in HttpClient.BaseAddress op
"https://jsonplaceholder.typicode.com"
.
In dit HttpClient
exemplaar wordt het basisadres gebruikt bij het indienen van volgende aanvragen. Als u andere configuraties wilt toepassen, kunt u het volgende overwegen:
- Instelling HttpClient.DefaultRequestHeaders.
- Een niet-standaard toe te HttpClient.Timeoutpassen .
- Geef de HttpClient.DefaultRequestVersion.
Tip
U kunt ook exemplaren maken HttpClient
met behulp van een factory-patroonbenadering waarmee u een willekeurig aantal clients kunt configureren en als afhankelijkheidsinjectieservices kunt gebruiken. Zie HTTP-clientfactory met .NET voor meer informatie.
Een HTTP-aanvraag maken
Als u een HTTP-aanvraag wilt indienen, roept u een van de volgende API's 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 |
†A-aanvraag
USER SPECIFIED
geeft aan dat deSendAsync
methode een geldige methode HttpMethodaccepteert.
Waarschuwing
Het maken van HTTP-aanvragen wordt beschouwd als netwerk-I/O-gebonden werk. Hoewel er een synchrone HttpClient.Send methode is, is het raadzaam om in plaats daarvan de asynchrone API's te gebruiken, tenzij u een goede reden hebt om dat niet te doen.
Notitie
Hoewel u zich richt op Android-apparaten (zoals bij .NET-ONTWIKKELING), moet u toevoegen android:usesCleartextTraffic="true"
aan <application></application>
AndroidManifest.xml. Hierdoor wordt tekstverhelderend verkeer mogelijk, zoals HTTP-aanvragen, dat anders standaard is uitgeschakeld vanwege een Android-beveiligingsbeleid. 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
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 is vereist, POST
enPUT
PATCH
, gebruikt u de klasse om de HttpContent 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
"application/x-www-form-urlencoded"
het MIME-type. - JsonContent: Biedt HTTP-inhoud op basis van JSON.
- MultipartContent: Biedt een verzameling HttpContent-objecten die worden geserialiseerd met behulp van de
"multipart/*"
MIME-typespecificatie. - MultipartFormDataContent: Biedt een container voor inhoud die is gecodeerd met behulp van
"multipart/form-data"
het MIME-type. - ReadOnlyMemoryContent: Biedt HTTP-inhoud op basis van een ReadOnlyMemory<T>.
- 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 HttpResponseMessageeigenschap weer te geven die toegankelijk is voor de HttpResponseMessage.Content eigenschap.
HTTP Get
Een GET
aanvraag mag geen hoofdtekst verzenden en wordt gebruikt (zoals de methodenaam aangeeft) om gegevens op te halen (of op te halen) uit een resource. Als u een HTTP-aanvraag GET
wilt doen, gebruikt u de HttpClient.GetAsync methode op basis van een HttpClient
en een URI:
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
// }
}
Met de voorgaande code wordt:
- Doet een
GET
verzoek aan"https://jsonplaceholder.typicode.com/todos/3"
. - Zorgt ervoor dat het antwoord is geslaagd.
- Hiermee schrijft u de aanvraaggegevens naar de console.
- Leest de hoofdtekst van het antwoord als een tekenreeks.
- Hiermee schrijft u de hoofdtekst van het JSON-antwoord naar de console.
Dit WriteRequestToConsole
is een aangepaste extensiemethode die geen deel uitmaakt van het framework, maar als u wilt weten hoe deze wordt geïmplementeerd, 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>
De aanvraag voor https://jsonplaceholder.typicode.com/todos/3
het GET
uitvoeren van het volgende bericht wordt bijvoorbeeld uitgevoerd:
GET https://jsonplaceholder.typicode.com/todos/3 HTTP/1.1
HTTP Get van JSON
Het https://jsonplaceholder.typicode.com/todos eindpunt retourneert een JSON-matrix met 'todo'-objecten. De JSON-structuur ziet er ongeveer als volgt uit:
[
{
"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 Inleiding tot recordtypen in C# voor meer informatie over het record
type. Als u aanvragen automatisch wilt deserialiseren GET
in een sterk getypeerd C#-object, gebruikt u de GetFromJsonAsync extensiemethode die deel uitmaakt van het NuGet-pakket System.Net.Http.Json .
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 }
}
In de voorgaande code:
- Er
GET
wordt een verzoek ingediend bij"https://jsonplaceholder.typicode.com/todos?userId=1&completed=false"
.- De querytekenreeks vertegenwoordigt de filtercriteria voor de aanvraag.
- Het antwoord wordt automatisch gedeserialiseerd in een
List<Todo>
wanneer dit lukt. - De aanvraagdetails worden samen met elk
Todo
object naar de console geschreven.
HTTP-bericht
Een POST
aanvraag verzendt gegevens naar de server voor verwerking. De Content-Type
header van de aanvraag geeft aan welk MIME-type de hoofdtekst wordt verzonden. Gebruik de HttpClient.PostAsync volgende methode om een HTTP-aanvraag POST
te maken, op basis van een HttpClient
en eenUri:
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
// }
}
Met de voorgaande code wordt:
- Bereidt een StringContent exemplaar voor met de JSON-hoofdtekst van de aanvraag (MIME-type).
"application/json"
- Doet een
POST
verzoek aan"https://jsonplaceholder.typicode.com/todos"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraaggegevens naar de console.
- Hiermee schrijft u de hoofdtekst van het antwoord als een tekenreeks naar de console.
HTTP Post 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 }
}
Met de voorgaande code wordt:
- Serialiseert het
Todo
exemplaar als JSON en verzendt eenPOST
aanvraag naar"https://jsonplaceholder.typicode.com/todos"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraaggegevens naar de console.
- Deserializeert de hoofdtekst van het antwoord in een
Todo
exemplaar en schrijft deTodo
naar de console.
HTTP Put
De PUT
aanvraagmethode vervangt een bestaande resource of maakt een nieuwe met behulp van de nettolading van de aanvraagbody. Als u een HTTP-aanvraag PUT
wilt doen, gebruikt u de HttpClient.PutAsync methode op basis van een HttpClient
en een URI:
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
// }
}
Met de voorgaande code wordt:
- Bereidt een StringContent exemplaar voor met de JSON-hoofdtekst van de aanvraag (MIME-type).
"application/json"
- Doet een
PUT
verzoek aan"https://jsonplaceholder.typicode.com/todos/1"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraagdetails en de hoofdtekst van het JSON-antwoord naar de console.
HTTP Put as 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 }
}
Met de voorgaande code wordt:
- Serialiseert het
Todo
exemplaar als JSON en verzendt eenPUT
aanvraag naar"https://jsonplaceholder.typicode.com/todos/5"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraaggegevens naar de console.
- Deserializeert de hoofdtekst van het antwoord in een
Todo
exemplaar en schrijft deTodo
naar de console.
HTTP-patch
De PATCH
aanvraag is een gedeeltelijke update van een bestaande resource. Er wordt geen nieuwe resource gemaakt en deze is niet bedoeld om een bestaande resource te vervangen. In plaats daarvan wordt een resource slechts gedeeltelijk bijgewerkt. Als u een HTTP-aanvraag PATCH
wilt doen, gebruikt u de HttpClient.PatchAsync methode op basis van een HttpClient
en een URI:
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
// }
}
Met de voorgaande code wordt:
- Bereidt een StringContent exemplaar voor met de JSON-hoofdtekst van de aanvraag (MIME-type).
"application/json"
- Doet een
PATCH
verzoek aan"https://jsonplaceholder.typicode.com/todos/1"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraagdetails en de hoofdtekst van het JSON-antwoord naar de console.
Er bestaan geen uitbreidingsmethoden voor PATCH
aanvragen in het System.Net.Http.Json
NuGet-pakket.
HTTP verwijderen
Een DELETE
aanvraag verwijdert een bestaande resource. Een DELETE
aanvraag is idempotent maar niet veilig, wat betekent dat meerdere DELETE
aanvragen voor dezelfde resources hetzelfde resultaat opleveren, maar de aanvraag is van invloed op de status van de resource. Als u een HTTP-aanvraag DELETE
wilt doen, gebruikt u de HttpClient.DeleteAsync methode op basis van een HttpClient
en een URI:
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
// {}
}
Met de voorgaande code wordt:
- Doet een
DELETE
verzoek aan"https://jsonplaceholder.typicode.com/todos/1"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraaggegevens naar de console.
Tip
Het antwoord op een DELETE
aanvraag (net als een PUT
aanvraag) kan al dan niet een hoofdtekst bevatten.
HTTP-hoofd
De HEAD
aanvraag is vergelijkbaar met een GET
aanvraag. In plaats van de resource te retourneren, worden alleen de headers geretourneerd die aan de resource zijn gekoppeld. Een antwoord op de HEAD
aanvraag retourneert geen hoofdtekst. Als u een HTTP-aanvraag HEAD
wilt maken op basis van een HttpClient
en een URI, gebruikt u de HttpClient.SendAsync methode met de HttpMethod set 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
}
Met de voorgaande code wordt:
- Doet een
HEAD
verzoek aan"https://www.example.com/"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraaggegevens naar de console.
- Herhaalt alle antwoordheaders en schrijft elke header naar de console.
HTTP-opties
De OPTIONS
aanvraag wordt gebruikt om te bepalen welke HTTP-methoden een server of eindpunt ondersteunt. Als u een HTTP-aanvraag OPTIONS
wilt maken op basis van een HttpClient
en een URI, gebruikt u de HttpClient.SendAsync methode met de HttpMethod set 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
}
Met de voorgaande code wordt:
- Verzendt een
OPTIONS
HTTP-aanvraag naar"https://www.example.com/"
. - Zorgt ervoor dat het antwoord is geslaagd en schrijft de aanvraaggegevens naar de console.
- Herhaalt alle headers van de antwoordinhoud en schrijft elke header naar de console.
HTTP-tracering
De TRACE
aanvraag kan handig zijn voor foutopsporing, omdat deze een lus op toepassingsniveau van het aanvraagbericht biedt. Als u een HTTP-aanvraag TRACE
wilt maken, maakt u een HttpRequestMessage met behulp van het HttpMethod.Trace
volgende:
using HttpRequestMessage request = new(
HttpMethod.Trace,
"{ValidRequestUri}");
Let op
De TRACE
HTTP-methode wordt niet ondersteund door alle HTTP-servers. Het kan een beveiligingsprobleem blootstellen als dit onverstandig wordt gebruikt. Zie Open Web Application Security Project (OWASP): Cross Site Tracing(Cross Site Tracing) voor meer informatie.
Een HTTP-antwoord verwerken
Wanneer u een HTTP-antwoord verwerkt, communiceert u met het HttpResponseMessage type. Verschillende leden worden gebruikt bij het evalueren van de geldigheid van een reactie. De HTTP-statuscode is beschikbaar via de HttpResponseMessage.StatusCode eigenschap. Stel dat u een aanvraag hebt verzonden op basis van een clientexemplaren:
using HttpResponseMessage response = await httpClient.SendAsync(request);
Om ervoor te zorgen dat de response
is OK
(HTTP-statuscode 200), kunt u deze 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 moet laten gooien HttpRequestException, kunt u de HttpResponseMessage.EnsureSuccessStatusCode() methode aanroepen:
response.EnsureSuccessStatusCode();
Deze code genereert een HttpRequestException
als de antwoordstatuscode zich niet binnen het bereik van 200-299 bevindt.
HTTP-geldige inhoudsreacties
Met een geldig antwoord hebt u toegang tot de hoofdtekst van het antwoord met behulp van de Content eigenschap. 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:
await using Stream responseStream =
await response.Content.ReadAsStreamAsync();
In de voorgaande code kan de responseStream
hoofdtekst van het antwoord worden gelezen.
byte[] responseByteArray = await response.Content.ReadAsByteArrayAsync();
In de voorgaande code kan de responseByteArray
hoofdtekst van het antwoord worden gelezen.
string responseString = await response.Content.ReadAsStringAsync();
In de voorgaande code kan de responseString
hoofdtekst van het antwoord worden gelezen.
Als 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 NuGet-pakket System.Net.Http.Json :
T? result = await response.Content.ReadFromJsonAsync<T>();
In de voorgaande code result
is de antwoordtekst gedeserialiseerd als het type T
.
HTTP-foutafhandeling
Wanneer een HTTP-aanvraag mislukt, wordt de HttpRequestException aanvraag gegenereerd. Het is mogelijk dat het niet voldoende is om deze uitzondering te ondervangen, omdat er andere mogelijke uitzonderingen zijn die u mogelijk wilt afhandelen. De aanroepende code kan bijvoorbeeld een annuleringstoken hebben gebruikt dat is geannuleerd voordat de aanvraag werd voltooid. In dit scenario ziet u het TaskCanceledExceptionvolgende:
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}");
}
En wanneer u een HTTP-aanvraag indient, wordt dezelfde uitzondering gegenereerd als de server niet reageert voordat de HttpClient.Timeout uitzondering wordt overschreden. In dit scenario kunt u echter onderscheid maken tussen de time-out door de Exception.InnerException volgende te evalueren:TaskCanceledException
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}");
}
In de voorgaande code, wanneer de interne uitzondering een TimeoutException time-out is opgetreden en de aanvraag niet is geannuleerd door het annuleringstoken.
Als u de HTTP-statuscode wilt evalueren bij het vangen van een HttpRequestException, kunt u de HttpRequestException.StatusCode eigenschap 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 voorgaande 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 HttpClient
die impliciet namens u worden aangeroepen EnsureSuccessStatusCode
. Houd rekening met de volgende API's:
Tip
Alle HttpClient
methoden die worden gebruikt om HTTP-aanvragen te maken die geen impliciete aanroep EnsureSuccessStatusCode
namens u retournerenHttpResponseMessage
.
Wanneer u deze methoden aanroept, kunt u de HttpRequestException
eigenschap afhandelen en evalueren HttpRequestException.StatusCode 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 de HttpRequestException code moet invoeren. De HttpRequestException() constructor is openbaar en u kunt deze gebruiken om een uitzondering te genereren met een aangepast bericht:
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}");
}
HTTP-proxy
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.
Algemene standaardproxy
Dit HttpClient.DefaultProxy
is een statische eigenschap die bepaalt welke standaardproxy alle HttpClient
exemplaren gebruiken als er geen proxy expliciet is ingesteld in de HttpClientHandler doorgegeven constructor.
Het standaardexemplaren dat door deze eigenschap wordt geretourneerd, initialiseert het volgen van een andere set regels, afhankelijk van uw platform:
- Voor Windows: leest de proxyconfiguratie van omgevingsvariabelen of, als deze niet zijn gedefinieerd, uit de proxy-instellingen van de gebruiker.
- Voor macOS: leest proxyconfiguratie uit omgevingsvariabelen of, als deze niet zijn gedefinieerd, uit de proxy-instellingen van het systeem.
- Voor Linux: leest de proxyconfiguratie van omgevingsvariabelen of, in het geval dat deze niet zijn gedefinieerd, initialiseert deze eigenschap een niet-geconfigureerd exemplaar dat alle adressen omzeilt.
De omgevingsvariabelen die worden gebruikt voor DefaultProxy
initialisatie op Windows- en Unix-platforms zijn:
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 voor HTTP- en/of HTTPS-aanvragen voor het gevalHTTP_PROXY
en/ofHTTPS_PROXY
niet zijn gedefinieerd.NO_PROXY
: een door komma's gescheiden lijst met hostnamen die moeten worden uitgesloten van proxying. Sterretjes worden niet ondersteund voor jokertekens; gebruik een voorlooppunt voor het geval u een subdomein wilt koppelen. Voorbeelden:NO_PROXY=.example.com
(met voorlooppunt) komt overeenwww.example.com
, maar komt niet overeenexample.com
.NO_PROXY=example.com
(zonder voorlooppunt) komt niet overeenwww.example.com
. Dit gedrag kan in de toekomst opnieuw worden bekeken om andere ecosystemen beter te vinden.
In systemen waarin omgevingsvariabelen hoofdlettergevoelig zijn, kunnen de namen van de variabelen allemaal kleine letters of 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 het kan een http
URL zijn, eventueel inclusief een gebruikersnaam en wachtwoord voor proxyverificatie. De URL moet beginnen met http
, niet https
en mag geen tekst bevatten na de hostnaam, het IP-adres of de poort.
Proxy per client
De HttpClientHandler.Proxy eigenschap identificeert het object dat moet worden gebruikt voor het WebProxy 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, overschrijft 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. De HttpClientHandler
klasse parseert bijvoorbeeld een bypass-lijst van "nt*"
browsers als een reguliere expressie van "nt.*"
. Een URL van de proxy wordt dus overgeslagen met behulp van http://nt.com
de HttpClientHandler
klasse.
De HttpClientHandler
klasse ondersteunt het omzeilen van lokale proxy's. De klasse beschouwt een bestemming als aan een van de volgende voorwaarden wordt voldaan:
- De bestemming bevat een platte naam (geen puntjes in de URL).
- De bestemming bevat een loopback-adres (Loopback of IPv6Loopback) of de bestemming bevat een IPAddress toegewezen aan de lokale computer.
- Het domeinachtervoegsel van de bestemming komt overeen met het domeinachtervoegsel van de lokale computer (DomainName).
Zie voor meer informatie over het configureren van een proxy: