Dela via


Göra HTTP-begäranden med klassen HttpClient

I den här artikeln får du lära dig hur du gör HTTP-begäranden och hanterar svar med klassen HttpClient.

Viktigt!

Alla HTTP-exempelbegäranden i den här artikeln riktar sig till någon av följande URL:er:

HTTP-slutpunkter returnerar vanligtvis JSON-data (JavaScript Object Notation), men inte alltid. För enkelhetens skull innehåller det valfria System.Net.Http.Json NuGet-paketet flera tilläggsmetoder för HttpClient- och HttpContent-objekt som utför automatisk serialisering och deserialisering med hjälp av 📦 System.Text.Json NuGet-paketet. Exemplen i den här artikeln uppmärksammar platser där dessa tillägg är tillgängliga.

Tips

All källkod som refereras i den här artikeln finns i GitHub: .NET Docs lagringsplats.

Skapa ett HttpClient-objekt

De flesta av exemplen i den här artikeln återanvänder samma HttpClient instans, så att du kan konfigurera instansen en gång och använda den för de återstående exemplen. Om du vill skapa ett HttpClient objekt använder du HttpClient-klasskonstruktorn. Mer information finns i Riktlinjer för att använda HttpClient.

// HttpClient lifecycle management best practices:
// https://learn.microsoft.com/dotnet/fundamentals/networking/http/httpclient-guidelines#recommended-use
private static HttpClient sharedClient = new()
{
    BaseAddress = new Uri("https://jsonplaceholder.typicode.com"),
};

Koden slutför följande uppgifter:

  • Instansiera en ny HttpClient instans som en static variabel. Enligt riktlinjerna för rekommenderar vi att du återanvänder HttpClient instanser under programmets livscykel.
  • Ange egenskapen HttpClient.BaseAddress till "https://jsonplaceholder.typicode.com".

Den här HttpClient-instansen använder basadressen för att göra efterföljande begäranden. Tänk på följande API:er för att tillämpa andra konfigurationer:

Tips

Du kan också skapa HttpClient instanser med hjälp av en metod med fabriksmönster som gör att du kan konfigurera valfritt antal klienter och använda dem som beroendeinmatningstjänster. Mer information finns i HTTP-klientfabriken med .NET.

Gör en HTTP-begäran

Om du vill göra en HTTP-begäran anropar du någon av följande API-metoder:

HTTP-metod API (programmeringsgränssnitt)
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

En USER SPECIFIED begäran anger att metoden SendAsync accepterar alla giltiga HttpMethod objekt.

Varning

Att göra HTTP-begäranden betraktas som nätverks-I/O-bundet arbete. Det finns en synkron HttpClient.Send metod, men rekommendationen är att använda asynkrona API:er i stället, såvida du inte har goda skäl att inte göra det.

Kommentar

När du riktar in dig på Android-enheter (till exempel med .NET MAUI-utveckling) måste du lägga till definitionen android:usesCleartextTraffic="true" i avsnittet <application></application> i AndroidManifest.xml-filen. Den här inställningen aktiverar klartexttrafik, till exempel HTTP-begäranden, som annars inaktiveras som standard på grund av Android-säkerhetsprinciper. Överväg följande XML-exempelinställningar:

<?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>

Mer information finns i Aktivera klartextnätverkstrafik för domänen localhost.

Förstå HTTP-innehåll

Typen HttpContent används för att representera en HTTP-entitetstext och motsvarande innehållshuvuden. För HTTP-metoder (eller begärandemetoder) som kräver en brödtext (POST, PUT, PATCH) använder du klassen HttpContent för att ange brödtexten för begäran. De flesta exempel visar hur du förbereder underklassen StringContent med en JSON-nyttolast, men det finns andra underklasser för olika typer av innehåll (MIME).

  • ByteArrayContent: Tillhandahåller HTTP-innehåll baserat på en bytematris.
  • FormUrlEncodedContent: Tillhandahåller HTTP-innehåll för namn/värde-tupplar som kodas med hjälp av "application/x-www-form-urlencoded" MIME-typ.
  • JsonContent: Tillhandahåller HTTP-innehåll baserat på JSON.
  • MultipartContent: Tillhandahåller en samling HttpContent-objekt som serialiseras med hjälp av specifikationen för "multipart/*" MIME-typ.
  • MultipartFormDataContent: Tillhandahåller en container för innehåll som kodas med hjälp av "multipart/form-data" MIME-typ.
  • ReadOnlyMemoryContent: Tillhandahåller HTTP-innehåll baserat på ett ReadOnlyMemory<T> värde.
  • StreamContent: Tillhandahåller HTTP-innehåll baserat på en dataström.
  • StringContent: Tillhandahåller HTTP-innehåll baserat på en sträng.

Klassen HttpContent används också för att representera svarstexten i klassen HttpResponseMessage, som är tillgänglig för egenskapen HttpResponseMessage.Content.

Använda en HTTP GET-begäran

En GET-begäran bör inte skicka något innehåll. Den här begäran används (som metodnamnet anger) för att hämta (eller hämta) data från en resurs. Om du vill göra en HTTP-GET begäran med en HttpClient-instans och ett Uri-objekt använder du metoden 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
    //   }
}

Koden slutför följande uppgifter:

  • Skicka en GET begäran till "https://jsonplaceholder.typicode.com/todos/3" slutpunkten.
  • Kontrollera att svaret är lyckat.
  • Skriv information om begäran till konsolen.
  • Läs svarstexten som en sträng.
  • Skriv JSON-svarstexten till konsolen.

Metoden WriteRequestToConsole är ett anpassat tillägg som inte ingår i ramverket. Om du är nyfiken på implementeringen bör du överväga följande C#-kod:

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}");        
    }
}

Den här funktionen används för att skriva information om begäran till konsolen i följande formulär:

<HTTP Request Method> <Request URI> <HTTP/Version>

Till exempel levererar begäran GET till slutpunkten "https://jsonplaceholder.typicode.com/todos/3" följande meddelande:

GET https://jsonplaceholder.typicode.com/todos/3 HTTP/1.1

Skapa HTTP GET-begäran från JSON

Den https://jsonplaceholder.typicode.com/todos slutpunkten returnerar en JSON-matris med Todo objekt. Deras JSON-struktur liknar följande formulär:

[
  {
    "userId": 1,
    "id": 1,
    "title": "example title",
    "completed": false
  },
  {
    "userId": 1,
    "id": 2,
    "title": "another example title",
    "completed": true
  },
]

C#- Todo objektet definieras på följande sätt:

public record class Todo(
    int? UserId = null,
    int? Id = null,
    string? Title = null,
    bool? Completed = null);

Det är en record class typ med valfria Idegenskaper , Title, Completedoch UserId . Mer information om typen finns record i Introduktion till posttyper i C#. Om du automatiskt vill deserialisera GET begäranden till ett starkt skrivet C#-objekt använder du GetFromJsonAsync-tilläggsmetoden som ingår i 📦 System.Net.Http.Json- NuGet-paketet.

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 }
}

Koden slutför följande uppgifter:

  • Gör en GET begäran till "https://jsonplaceholder.typicode.com/todos?userId=1&completed=false".

    Frågesträngen representerar filtreringsvillkoren för begäran. När kommandot lyckas deserialiseras svaret automatiskt till ett List<Todo> objekt.

  • Skriv information om begäran till konsolen tillsammans med varje Todo objekt.

Använda en HTTP POST-begäran

En POST begäran skickar data till servern för bearbetning. Rubriken Content-Type för begäran anger vilken MIME-typ som brödtexten skickar. Om du vill göra en HTTP-POST begäran med en HttpClient-instans och ett Uri-objekt använder du metoden 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
    //   }
}

Koden slutför följande uppgifter:

  • Förbered en StringContent-instans med JSON-innehållet i begäran (MIME-typ av "application/json").
  • Skicka en POST begäran till "https://jsonplaceholder.typicode.com/todos" slutpunkten.
  • Se till att svaret är lyckat och skriv information om begäran till konsolen.
  • Skriv svarstexten som en sträng till konsolen.

Skapa HTTP POST-begäran som JSON

Om du vill serialisera POST begärandeargument automatiskt och deserialisera svar till starkt skrivna C#-objekt använder du tilläggsmetoden PostAsJsonAsync som ingår i NuGet-paketet 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 }
}

Koden slutför följande uppgifter:

  • Serialisera Todo-instansen som JSON och gör en POST begäran till "https://jsonplaceholder.typicode.com/todos" slutpunkten.
  • Se till att svaret är lyckat och skriv information om begäran till konsolen.
  • Deserialisera svarstexten till en Todo-instans och skriv Todo-objektet till konsolen.

Använda en HTTP PUT-begäran

Begärningsmetoden PUT ersätter antingen en befintlig resurs eller skapar en ny genom att använda innehållet i begärans kropp. Om du vill göra en HTTP-PUT begäran med en HttpClient-instans och ett Uri-objekt använder du metoden 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
    //   }
}

Koden slutför följande uppgifter:

  • Förbered en StringContent-instans med JSON-innehållet i begäran (MIME-typ av "application/json").
  • Skicka en PUT begäran till "https://jsonplaceholder.typicode.com/todos/1" slutpunkten.
  • Säkerställ att svaret är framgångsrikt och skriv begärans detaljer med JSON-svarskroppen till konsolen.

Skapa HTTP PUT-begäran som JSON

Om du vill serialisera PUT begärandeargument automatiskt och deserialisera svar till starkt skrivna C#-objekt använder du tilläggsmetoden PutAsJsonAsync som ingår i NuGet-paketet 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 }
}

Koden slutför följande uppgifter:

  • Serialisera Todo-instansen som JSON och gör en PUT begäran till "https://jsonplaceholder.typicode.com/todos/5" slutpunkten.
  • Se till att svaret är lyckat och skriv information om begäran till konsolen.
  • Deserialisera svarstexten till en Todo-instans och skriv Todo-objekten till konsolen.

Använd en HTTP PATCH-begäran

Begäran PATCH är en partiell uppdatering av en befintlig resurs. Den här begäran skapar ingen ny resurs och är inte avsedd att ersätta en befintlig resurs. I stället uppdaterar den här metoden endast delvis en resurs. Om du vill göra en HTTP-PATCH begäran med en HttpClient-instans och ett Uri-objekt använder du metoden 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
    //   }
}

Koden slutför följande uppgifter:

  • Förbered en StringContent-instans med JSON-innehållet i begäran (MIME-typ av "application/json").
  • Skicka en PATCH begäran till "https://jsonplaceholder.typicode.com/todos/1" slutpunkten.
  • Säkerställ att svaret är framgångsrikt och skriv begärans detaljer med JSON-svarskroppen till konsolen.

Det finns inga tilläggsmetoder för PATCH begäranden i System.Net.Http.Json NuGet-paketet.

Använda en HTTP DELETE-begäran

En DELETE begäran tar bort en befintlig resurs och begäran är idempotent, men inte säker. Flera DELETE begäranden till samma resurser ger samma resultat, men begäran påverkar resursens tillstånd. Om du vill göra en HTTP-DELETE begäran med en HttpClient-instans och ett Uri-objekt använder du metoden 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
    //   {}
}

Koden slutför följande uppgifter:

  • Skicka en DELETE begäran till "https://jsonplaceholder.typicode.com/todos/1" slutpunkten.
  • Se till att svaret är lyckat och skriv information om begäran till konsolen.

Tips

Svaret på en DELETE-begäran (precis som en PUT-begäran) kan eller kan inte innehålla aktivt innehåll.

Utforska HTTP HEAD-begäran

Begäran HEAD liknar en GET begäran. I stället för att returnera resursen returnerar den här begäran endast de rubriker som är associerade med resursen. Ett svar på HEAD-begäran returnerar inte en kropp. Om du vill göra en HTTP-HEAD begäran med en HttpClient-instans och ett Uri-objekt använder du metoden HttpClient.SendAsync med den HttpMethod typen inställd på 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
}

Koden slutför följande uppgifter:

  • Skicka en HEAD begäran till "https://www.example.com/" slutpunkten.
  • Se till att svaret är lyckat och skriv information om begäran till konsolen.
  • Iterera över alla svarshuvuden och skriv varje rubrik till konsolen.

Utforska HTTP OPTIONS-begäran

Begäran OPTIONS används för att identifiera vilka HTTP-metoder en server eller slutpunkt stöder. Om du vill göra en HTTP-OPTIONS begäran med en HttpClient-instans och ett Uri-objekt använder du metoden HttpClient.SendAsync med den HttpMethod typen inställd på 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
}

Koden slutför följande uppgifter:

  • Skicka en OPTIONS HTTP-begäran till "https://www.example.com/" slutpunkten.
  • Se till att svaret är lyckat och skriv information om begäran till konsolen.
  • Iterera över alla svarsinnehållshuvuden och skriv varje rubrik till konsolen.

Utforska HTTP TRACE-begäran

Begäran TRACE kan vara användbar för felsökning eftersom den tillhandahåller loop-back på programnivå i begärandemeddelandet. Om du vill göra en HTTP-TRACE begäran skapar du en HttpRequestMessage med hjälp av den HttpMethod.Trace typen:

using HttpRequestMessage request = new(
    HttpMethod.Trace, 
    "{ValidRequestUri}");

Varning

Alla HTTP-servrar stöder inte http-metoden TRACE. Den här metoden kan exponera en säkerhetsrisk om den används på ett okloligt sätt. Mer information finns i Open Web Application Security Project (OWASP): Spårning mellan webbplatser.

Hantera ett HTTP-svar

När du hanterar ett HTTP-svar interagerar du med den HttpResponseMessage typen. Flera medlemmar används för att utvärdera giltigheten för ett svar. HTTP-statuskoden är tillgänglig i egenskapen HttpResponseMessage.StatusCode.

Anta att du skickar en begäran från en klientinstans:

using HttpResponseMessage response = await httpClient.SendAsync(request);

För att säkerställa att response är OK (HTTP-statuskod 200) kan du utvärdera värdet enligt följande exempel:

if (response is { StatusCode: HttpStatusCode.OK })
{
    // Omitted for brevity...
}

Det finns andra HTTP-statuskoder som representerar ett lyckat svar, till exempel CREATED (HTTP-statuskod 201), ACCEPTED (HTTP-statuskod 202), NO CONTENT (HTTP-statuskod 204) och RESET CONTENT (HTTP-statuskod 205). Du kan också använda HttpResponseMessage.IsSuccessStatusCode egenskapen för att utvärdera dessa koder, vilket säkerställer att svarsstatuskoden ligger inom intervallet 200–299:

if (response.IsSuccessStatusCode)
{
    // Omitted for brevity...
}

Om du behöver få ramverket att utlösa HttpRequestException-felet kan du anropa metoden HttpResponseMessage.EnsureSuccessStatusCode():

response.EnsureSuccessStatusCode();

Den här koden genererar ett HttpRequestException fel om svarsstatuskoden inte ligger inom intervallet 200–299.

Utforska HTTP-giltiga innehållssvar

Med ett giltigt svar kan du komma åt svarstexten med hjälp av egenskapen Content. Brödtexten är tillgänglig som en HttpContent instans, som du kan använda för att komma åt brödtexten som en ström, bytematris eller sträng.

Följande kod använder objektet responseStream för att läsa svarstexten:

await using Stream responseStream =
    await response.Content.ReadAsStreamAsync();

Du kan använda olika objekt för att läsa svarstexten. Använd responseByteArray-objektet för att läsa svarstexten:

byte[] responseByteArray = await response.Content.ReadAsByteArrayAsync();

Använd responseString-objektet för att läsa svarstexten:

string responseString = await response.Content.ReadAsStringAsync();

När du vet att en HTTP-slutpunkt returnerar JSON kan du deserialisera svarstexten till valfritt giltigt C#-objekt med hjälp av System.Net.Http.Json NuGet-paketet:

T? result = await response.Content.ReadFromJsonAsync<T>();

I den här koden är result-värdet svarstexten deserialiserad till typen T.

Använda HTTP-felhantering

När en HTTP-begäran misslyckas genererar systemet HttpRequestException-objektet. Det kanske inte räcker att endast fånga undantaget. Det finns andra möjliga undantag som du kanske vill överväga att hantera. Till exempel kan koden som anropar använda en annulleringssignal som avbröts innan begäran slutfördes. I det här scenariot kan du upptäcka TaskCanceledException-felet:

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}");
}

När du gör en HTTP-begäran utlöses samma undantag om servern inte svarar innan värdet för HttpClient.Timeout överskrids. I det här scenariot kan du avgöra att tidsgränsen inträffade genom att utvärdera egenskapen Exception.InnerException när du fångar TaskCanceledException-felet:

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}");
}

I koden, när det inre undantaget är av typen TimeoutException, har tidsgränsen inträffat och avbrytartoken avbryter inte begäran.

Om du vill utvärdera HTTP-statuskoden när du fångar HttpRequestException-objektet kan du utvärdera egenskapen HttpRequestException.StatusCode:

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}");
}

I koden anropas metoden EnsureSuccessStatusCode() för att utlösa ett undantag om svaret inte lyckas. Egenskapen HttpRequestException.StatusCode utvärderas sedan för att avgöra om svaret var en 404 (HTTP-statuskod 404). Det finns flera hjälpmetoder på HttpClient-objektet som implicit anropar metoden EnsureSuccessStatusCode för din räkning.

Tänk på följande API:er för HTTP-felhantering:

Tips

Alla HttpClient metoder som används för att göra HTTP-begäranden som inte returnerar en HttpResponseMessage typ anropar implicit EnsureSuccessStatusCode-metoden för din räkning.

När du anropar dessa metoder kan du hantera HttpRequestException-objektet och utvärdera egenskapen HttpRequestException.StatusCode för att fastställa HTTP-statuskoden för svaret:

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}");
}

Det kan finnas scenarier där du behöver kasta HttpRequestException-objektet i koden. Konstruktorn HttpRequestException() är offentlig och du kan använda den för att utlösa ett undantag med ett anpassat meddelande:

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}");
}

Konfigurera en HTTP-proxy

En HTTP-proxy kan konfigureras på något av två sätt. Ett standardvärde anges för egenskapen HttpClient.DefaultProxy . Du kan också ange en proxy för egenskapen HttpClientHandler.Proxy .

Använd en global standardproxy

Egenskapen HttpClient.DefaultProxy är en statisk egenskap som avgör standardproxyn som alla HttpClient-instanser använder, om ingen proxy anges uttryckligen i det HttpClientHandler objekt som skickas via konstruktorn.

Standardinstansen som returneras av den här egenskapen initieras enligt en annan uppsättning regler beroende på din plattform:

  • Windows: Läs proxykonfigurationen från miljövariablerna, eller om variablerna inte är definierade, läs från användarens proxyinställningar.
  • macOS: Läs proxykonfiguration från miljövariabler, eller om variabler inte har definierats, läs från systemets proxyinställningar.
  • Linux-: Läs proxykonfigurationen från miljövariablerna, eller om variablerna inte är definierade, initiera en oconfigurerad instans för att gå förbi alla adresser.

Initieringen av DefaultProxy-egenskapen på Windows- och Unix-baserade plattformar använder följande miljövariabler:

  • HTTP_PROXY: Proxyservern som används för HTTP-begäranden.
  • HTTPS_PROXY: Proxyservern som används för HTTPS-begäranden.
  • ALL_PROXY: Proxyservern som används på HTTP- och/eller HTTPS-begäranden när HTTP_PROXY och/eller HTTPS_PROXY variabler inte definieras.
  • NO_PROXY: En kommaavgränsad lista över värdnamn som ska undantas från proxy. Asterisker kan inte användas som jokertecken. Använd en inledande punkt (.) när du vill matcha en underdomän. Exempel: NO_PROXY=.example.com (med inledande period) matchar www.example.com, men matchar inte example.com. NO_PROXY=example.com (utan inledande period) matchar inte www.example.com. Det här beteendet kan ses över i framtiden för att matcha andra ekosystem bättre.

På system där miljövariabler är skiftlägeskänsliga kan variabelnamnen vara endast gemener eller endast versaler. De små bokstäverna i namn kontrolleras först.

Proxyservern kan vara ett värdnamn eller EN IP-adress, eventuellt följt av ett kolon- och portnummer, eller så kan det vara en http URL, om du vill inkludera ett användarnamn och lösenord för proxyautentisering. URL:en måste börja med http, inte httpsoch kan inte innehålla någon text efter värdnamnet, IP-adressen eller porten.

Konfigurera proxyservern per klient

Egenskapen HttpClientHandler.Proxy identifierar det WebProxy objekt som ska användas för att bearbeta begäranden till Internetresurser. Om du vill ange att ingen proxy ska användas anger du Proxy egenskapen till den proxyinstans som returneras av GlobalProxySelection.GetEmptyWebProxy() metoden.

Den lokala datorn eller programkonfigurationsfilen kan ange att en standardproxy används. Om egenskapen Proxy anges åsidosätter proxyinställningarna från egenskapen Proxy den lokala datorn eller programkonfigurationsfilen och hanteraren använder de angivna proxyinställningarna. Om ingen proxy anges i en konfigurationsfil och egenskapen Proxy är ospecificerad använder hanteraren proxyinställningarna som ärvts från den lokala datorn. Om det inte finns några proxyinställningar skickas begäran direkt till servern.

Klassen HttpClientHandler parsar en proxy-undantagslista med jokertecken som ärvts från lokala datorinställningar. Klassen tolkar till exempel en förbikopplingslista från webbläsare som ett reguljärt uttryck i HttpClientHandler, "nt*", "nt.*". Därför kringgår en URL för http://nt.com proxyn med hjälp av klassen HttpClientHandler.

Klassen HttpClientHandler stöder lokal proxy bypass. Klassen anser att ett mål är lokalt om något av följande villkor uppfylls:

  • Destinationen innehåller ett namn utan punkter (inga punkter (.) i URL:en).
  • Målet innehåller en loopback-adress (Loopback eller IPv6Loopback) eller målet innehåller en IPAddress egenskap som tilldelats den lokala datorn.
  • Målets domänsuffix matchar den lokala datorns domänsuffix enligt definitionen i egenskapen DomainName.

Mer information om hur du konfigurerar en proxy finns i följande API:er:

Nästa steg