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:
- https://jsonplaceholder.typicode.com: Kostnadsfritt falskt API för testning och prototyper.
- https://www.example.com: Den här domänen används i illustrativa exempel i dokument.
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 HttpClient
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 ovan:
- Instansierar en ny
HttpClient
instans som enstatic
variabel. Enligt riktlinjerna rekommenderar vi att du återanvänderHttpClient
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å:
- Ange HttpClient.DefaultRequestHeaders.
- Tillämpa en nondefault HttpClient.Timeout.
- HttpClient.DefaultRequestVersionAnge .
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 attSendAsync
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, , POST
PUT
och 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 Id
egenskaper , Title
, Completed
och 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 enPOST
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 skriverTodo
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 enPUT
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 skriverTodo
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 omHTTP_PROXY
och/ellerHTTPS_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) matcharwww.example.com
, men matcharexample.com
inte .NO_PROXY=example.com
(utan inledande punkt) matcharwww.example.com
inte . 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 https
och 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:
- Målet innehåller ett platt namn (inga punkter i URL:en).
- Målet innehåller en loopback-adress (Loopback eller IPv6Loopback) eller målet innehåller en IPAddress tilldelad till den lokala datorn.
- Målets domänsuffix matchar den lokala datorns domänsuffix (DomainName).
Mer information om hur du konfigurerar en proxy finns i: