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:

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 HttpClientte 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 een static variabele. Volgens de richtlijnen is het raadzaam om instanties opnieuw te gebruiken HttpClient 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:

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

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, POSTenPUTPATCH, 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).

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

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 geval 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. 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 overeen www.example.com, maar komt niet overeen example.com. NO_PROXY=example.com (zonder voorlooppunt) komt niet overeen www.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 httpsen 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:

  1. De bestemming bevat een platte naam (geen puntjes in de URL).
  2. De bestemming bevat een loopback-adres (Loopback of IPv6Loopback) of de bestemming bevat een IPAddress toegewezen aan de lokale computer.
  3. 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:

Zie ook