Delen via


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:

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 een static variabele. Volgens de richtlijnen, is de aanbevolen aanpak om HttpClient 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:

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 de SendAsync-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).

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, Titleen Completedeigenschappen 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 een POST 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 het Todo-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 een PUT 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 de Todo 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:

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 variabelen HTTP_PROXY en/of HTTPS_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 met www.example.com, maar komt niet overeen met example.com. NO_PROXY=example.com (zonder voorloopperiode) komt niet overeen met www.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 httpsen 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:

Volgende stappen