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 HttpClient klassen.

Viktigt!

Alla HTTP-exempelbegäranden 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 NuGet-paketet System.Net.Http.Json flera tilläggsmetoder för HttpClient och HttpContent som utför automatisk serialisering och deserialisering med .System.Text.Json Exemplen som följer uppmärksammar platser där dessa tillägg är tillgängliga.

Dricks

All källkod från den här artikeln är tillgänglig på GitHub: .NET Docs-lagringsplatsen .

Skapa en HttpClient

De flesta av följande exempel återanvänder samma HttpClient instans och behöver därför bara konfigureras en gång. Om du vill skapa en HttpClientanvä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 ovan:

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

Den här HttpClient instansen använder basadressen när du gör efterföljande begäranden. Om du vill använda en annan konfiguration bör du tänka på:

Dricks

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ågot av följande API:er:

HTTP-metod 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-begäran USER SPECIFIED anger att SendAsync metoden accepterar alla giltiga HttpMethod.

Varning

Att göra HTTP-begäranden betraktas som nätverks-I/O-bundet arbete. Även om det finns en synkron HttpClient.Send metod rekommenderar vi att du använder 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 android:usesCleartextTraffic="true" i AndroidManifest.xml.<application></application> Detta möjliggör 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.

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, , POSTPUToch PATCH, använder HttpContent du klassen 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 MIME-typ "application/x-www-form-urlencoded" .
  • JsonContent: Tillhandahåller HTTP-innehåll baserat på JSON.
  • MultipartContent: Tillhandahåller en samling HttpContent-objekt som serialiseras med mime-typspecifikationen "multipart/*" .
  • MultipartFormDataContent: Tillhandahåller en container för innehåll som kodas med MIME-typ "multipart/form-data" .
  • ReadOnlyMemoryContent: Tillhandahåller HTTP-innehåll baserat på en ReadOnlyMemory<T>.
  • 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 HttpResponseMessageegenskapen , som är tillgänglig för egenskapen HttpResponseMessage.Content .

HTTP Get

En GET begäran ska inte skicka en brödtext och 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-begäran GET , med en HttpClient och en URI, använder du HttpClient.GetAsync metoden:

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 ovan:

  • Skickar en GET begäran till "https://jsonplaceholder.typicode.com/todos/3".
  • Säkerställer att svaret lyckas.
  • Skriver information om begäran till konsolen.
  • Läser svarstexten som en sträng.
  • Skriver JSON-svarstexten till konsolen.

WriteRequestToConsole Är en anpassad tilläggsmetod som inte ingår i ramverket, men om du är nyfiken på hur det implementeras 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 GET skickar begäran om att https://jsonplaceholder.typicode.com/todos/3 skicka följande meddelande:

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

HTTP Hämta från JSON

Slutpunkten https://jsonplaceholder.typicode.com/todos returnerar en JSON-matris med "todo"-objekt. Deras JSON-struktur liknar följande:

[
  {
    "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 tilläggsmetoden GetFromJsonAsync som ingår i NuGet-paketet 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 }
}

I koden ovan:

  • En GET begäran görs till "https://jsonplaceholder.typicode.com/todos?userId=1&completed=false".
    • Frågesträngen representerar filtreringsvillkoren för begäran.
  • Svaret deserialiseras automatiskt till en List<Todo> när det lyckas.
  • Begärandeinformationen skrivs till konsolen, tillsammans med varje Todo objekt.

HTTP-inlägg

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-begäran POST , med en HttpClient och en Uri, använder du HttpClient.PostAsync metoden:

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 ovan:

  • Förbereder en StringContent instans med JSON-brödtexten i begäran (MIME-typ av "application/json").
  • Skickar en POST begäran till "https://jsonplaceholder.typicode.com/todos".
  • Säkerställer att svaret lyckas och skriver information om begäran till konsolen.
  • Skriver svarstexten som en sträng till konsolen.

HTTP-inlägg 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 ovan:

  • Serialiserar instansen Todo som JSON och skickar en POST begäran till "https://jsonplaceholder.typicode.com/todos".
  • Säkerställer att svaret lyckas och skriver information om begäran till konsolen.
  • Deserialiserar svarstexten till en Todo instans och skriver Todo till konsolen.

HTTP-put

Begärandemetoden PUT ersätter antingen en befintlig resurs eller skapar en ny med hjälp av nyttolasten för begärandetexten. Om du vill göra en HTTP-begäran PUT , med en HttpClient och en URI, använder du HttpClient.PutAsync metoden:

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 ovan:

  • Förbereder en StringContent instans med JSON-brödtexten i begäran (MIME-typ av "application/json").
  • Skickar en PUT begäran till "https://jsonplaceholder.typicode.com/todos/1".
  • Säkerställer att svaret lyckas och skriver begärandeinformationen och JSON-svarstexten till konsolen.

HTTP-insatt 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 ovan:

  • Serialiserar instansen Todo som JSON och skickar en PUT begäran till "https://jsonplaceholder.typicode.com/todos/5".
  • Säkerställer att svaret lyckas och skriver information om begäran till konsolen.
  • Deserialiserar svarstexten till en Todo instans och skriver Todo till konsolen.

HTTP-korrigering

Begäran PATCH är en partiell uppdatering av en befintlig resurs. Den skapar ingen ny resurs och är inte avsedd att ersätta en befintlig resurs. I stället uppdateras en resurs endast delvis. Om du vill göra en HTTP-begäran PATCH , med en HttpClient och en URI, använder du HttpClient.PatchAsync metoden:

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 ovan:

  • Förbereder en StringContent instans med JSON-brödtexten i begäran (MIME-typ av "application/json").
  • Skickar en PATCH begäran till "https://jsonplaceholder.typicode.com/todos/1".
  • Säkerställer att svaret lyckas och skriver begärandeinformationen och JSON-svarstexten till konsolen.

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

HTTP-borttagning

En DELETE begäran tar bort en befintlig resurs. En DELETE begäran är idempotent men inte säker, vilket innebär att 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-begäran DELETE , med en HttpClient och en URI, använder du HttpClient.DeleteAsync metoden:

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 ovan:

  • Skickar en DELETE begäran till "https://jsonplaceholder.typicode.com/todos/1".
  • Säkerställer att svaret lyckas och skriver information om begäran till konsolen.

Dricks

Svaret på en DELETE begäran (precis som en PUT begäran) kan innehålla en brödtext.

HTTP-huvud

Begäran HEAD liknar en GET begäran. I stället för att returnera resursen returneras bara de rubriker som är associerade med resursen. Ett svar på HEAD begäran returnerar inte en brödtext. Om du vill göra en HTTP-begäran HEAD , givet en HttpClient och en URI, använder du HttpClient.SendAsync metoden med HttpMethod inställningen 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 ovan:

  • Skickar en HEAD begäran till "https://www.example.com/".
  • Säkerställer att svaret lyckas och skriver information om begäran till konsolen.
  • Itererar över alla svarshuvuden och skriver var och en till konsolen.

HTTP-alternativ

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-begäran OPTIONS , givet en HttpClient och en URI, använder du HttpClient.SendAsync metoden med HttpMethod inställningen 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 ovan:

  • Skickar en OPTIONS HTTP-begäran till "https://www.example.com/".
  • Säkerställer att svaret lyckas och skriver information om begäran till konsolen.
  • Itererar över alla svarsinnehållsrubriker och skriver var och en till konsolen.

HTTP-spårning

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

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

Varning

TRACE HTTP-metoden stöds inte av alla HTTP-servrar. Det kan exponera en säkerhetsrisk om den används oklokan. 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 HttpResponseMessage typen. Flera medlemmar används vid utvärdering av giltigheten för ett svar. HTTP-statuskoden är tillgänglig via egenskapen HttpResponseMessage.StatusCode . Anta att du har skickat en begäran med en klientinstans:

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

För att säkerställa att response is OK (HTTP-statuskod 200) kan du utvärdera det 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 ramverket för att generera HttpRequestExceptionkan du anropa HttpResponseMessage.EnsureSuccessStatusCode() metoden:

response.EnsureSuccessStatusCode();

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

HTTP-giltiga innehållssvar

Med ett giltigt svar kan du komma åt svarstexten Content med hjälp av egenskapen . 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:

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

I föregående kod responseStream kan användas för att läsa svarstexten.

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

I föregående kod responseByteArray kan användas för att läsa svarstexten.

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

I föregående kod responseString kan användas för att läsa svarstexten.

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

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

I föregående kod result är svarstexten deserialiserad som typen T.

HTTP-felhantering

När en HTTP-begäran misslyckas genereras den HttpRequestException . Det kanske inte räcker att fånga undantaget ensamt, eftersom det finns andra möjliga undantag som du kanske vill överväga att hantera. Till exempel kan den anropande koden ha använt en annulleringstoken som avbröts innan begäran slutfördes. I det här scenariot skulle du fånga TaskCanceledException:

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

På samma sätt, när du gör en HTTP-begäran, om servern inte svarar innan överskrids HttpClient.Timeout utlöses samma undantag. I det här scenariot kan du dock skilja på att tidsgränsen inträffade genom att Exception.InnerException utvärdera när du fångade 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}");
}

I föregående kod, när det inre undantaget är en TimeoutException timeout inträffade och begäran inte avbröts av annulleringstoken.

Om du vill utvärdera HTTP-statuskoden när du fångar en HttpRequestExceptionkan 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 föregående kod EnsureSuccessStatusCode() anropas metoden 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 HttpClient för som implicit anropar EnsureSuccessStatusCode åt dig. Tänk på följande API:er:

Dricks

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

När du anropar dessa metoder kan du hantera HttpRequestException och utvärdera HttpRequestException.StatusCode egenskapen 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 in 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}");
}

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 .

Global standardproxy

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

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

  • För Windows: Läser proxykonfiguration från miljövariabler eller, om de inte har definierats, från användarens proxyinställningar.
  • För macOS: Läser proxykonfiguration från miljövariabler eller, om de inte har definierats, från systemets proxyinställningar.
  • För Linux: Läser proxykonfiguration från miljövariabler eller, om de inte har definierats, initierar den här egenskapen en icke-konfigurerad instans som kringgår alla adresser.

Miljövariablerna som används för DefaultProxy initiering på Windows- och Unix-baserade plattformar är:

  • 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 om HTTP_PROXY och/eller HTTPS_PROXY inte har definierats.
  • NO_PROXY: en kommaavgränsad lista över värdnamn som ska undantas från proxy. Asterisker stöds inte för jokertecken. använd en inledande punkt om du vill matcha en underdomän. Exempel: NO_PROXY=.example.com (med inledande punkt) matchar www.example.com, men matchar example.cominte . NO_PROXY=example.com (utan inledande punkt) matchar www.example.cominte . Det här beteendet kan ses över i framtiden för att matcha andra ekosystem bättre.

I system där miljövariabler är skiftlägeskänsliga kan variabelnamnen vara alla gemener eller versaler. Gemenerna 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, inklusive 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.

Proxy per klient

Egenskapen HttpClientHandler.Proxy identifierar objektet som WebProxy 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-förbikopplingslista med jokertecken som ärvts från lokala datorinställningar. Klassen parsar till exempel HttpClientHandler en förbikopplingslista från "nt*" webbläsare som ett reguljärt uttryck för "nt.*". En URL för skulle därför kringgå proxyn med hjälp av http://nt.com HttpClientHandler -klassen.

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

  1. Målet innehåller ett platt namn (inga punkter i URL:en).
  2. Målet innehåller en loopback-adress (Loopback eller IPv6Loopback) eller målet innehåller en IPAddress tilldelad till den lokala datorn.
  3. Målets domänsuffix matchar den lokala datorns domänsuffix (DomainName).

Mer information om hur du konfigurerar en proxy finns i:

Se även