Megosztás a következőn keresztül:


HTTP-kérések létrehozása a HttpClient-osztálysal

Ebben a cikkben megtudhatja, hogyan hozhat létre HTTP-kéréseket, és hogyan kezelheti a válaszokat az HttpClient osztálysal.

Fontos

Az összes példa HTTP-kérés az alábbi URL-címek egyikére irányul:

A HTTP-végpontok általában JavaScript Object Notation (JSON) adatokat adnak vissza, de nem mindig. Az egyszerűség kedvéért az opcionális System.Net.Http.Json NuGet csomag számos bővítménymetelyt HttpClient biztosít, amelyek HttpContent automatikus szerializálást és deszerializálást hajtanak végre System.Text.Json. Az alábbi példák felhívják a figyelmet azokra a helyekre, ahol ezek a bővítmények elérhetők.

Tipp.

A cikk összes forráskódja elérhető a GitHubon: .NET Docs-adattárban .

Hozzon létre egy HttpClient

Az alábbi példák többsége ugyanazt HttpClient a példányt használja újra, ezért csak egyszer kell konfigurálni. Hozzon létre egy HttpClientosztálykonstruktort HttpClient . További információkért tekintse meg a HttpClient használatának irányelveit.

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

A fenti kód a következőket végzi el:

  • Új példány példányosítása HttpClient változóként static . Az irányelveknek megfelelően ajánlott a példányok újrafelhasználása HttpClient az alkalmazás életciklusa során.
  • A következőre állítja a HttpClient.BaseAddress következőt "https://jsonplaceholder.typicode.com": .

Ez a HttpClient példány az alapcímet használja a későbbi kérések során. Egyéb konfigurációk alkalmazásához fontolja meg a következő szempontokat:

Tipp.

Másik lehetőségként létrehozhat példányokat egy gyári mintaalapú megközelítéssel, amellyel tetszőleges számú ügyfelet konfigurálhat HttpClient , és függőséginjektálási szolgáltatásként használhatja őket. További információ: HTTP-ügyfél-előállító a .NET-tel.

HTTP-kérés létrehozása

HTTP-kérés indításához hívja meg az alábbi API-k bármelyikét:

HTTP method 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 USER SPECIFIED kérés azt jelzi, hogy a SendAsync metódus bármilyen érvényes HttpMethodelemet elfogad.

Figyelmeztetés

A HTTP-kérések létrehozása hálózati I/O-kötött munka. Bár létezik szinkron HttpClient.Send módszer, javasoljuk, hogy inkább az aszinkron API-kat használja, hacsak nincs rá jó oka.

Feljegyzés

Az Android-eszközök (például a .NET MAUI-fejlesztés) megcélzása közben hozzá kell adnia android:usesCleartextTraffic="true" a <application></application> AndroidManifest.xml. Ez lehetővé teszi a tiszta szöveges forgalmat, például a HTTP-kéréseket, amelyek egyébként alapértelmezés szerint le vannak tiltva az Android biztonsági szabályzatai miatt. Vegye figyelembe a következő példa XML-beállításokat:

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

További információ: Clear-text hálózati forgalom engedélyezése a localhost tartomány számára.

HTTP-tartalom

A HttpContent típus egy HTTP-entitás törzsét és a megfelelő tartalomfejléceket jelöli. A törzset POSTPUTPATCHigénylő HTTP-metódusok (vagy kérési metódusok) esetében az HttpContent osztály használatával adhatja meg a kérés törzsét. A legtöbb példa bemutatja, hogyan készítse elő az StringContent alosztályt egy JSON hasznos adattal, de más alosztályok léteznek különböző tartalomtípusokhoz (MIME).

Az HttpContent osztály a tulajdonságon HttpResponseMessage.Content elérhető válasz törzsének HttpResponseMessageábrázolására is használható.

HTTP Get

A GET kérések nem küldhetnek törzset, és (ahogy a metódus neve is jelzi) adatok lekérésére (vagy lekérésére) szolgálnak egy erőforrásból. HTTP-kérés GET HttpClient és URI igényléséhez használja a HttpClient.GetAsync következő módszert:

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

A fenti kód a következőket végzi el:

  • Kérést küld a ()GET > számára "https://jsonplaceholder.typicode.com/todos/3".
  • Biztosítja, hogy a válasz sikeres legyen.
  • A kérelem részleteit a konzolra írja.
  • Sztringként olvassa be a válasz törzsét.
  • A JSON-válasz törzsét a konzolra írja.

Ez WriteRequestToConsole egy egyéni bővítménymetódus, amely nem része a keretrendszernek, de ha kíváncsi a implementálásra, vegye figyelembe a következő C#-kódot:

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

Ez a funkció a kérés részleteinek a konzolra való írására szolgál az alábbi formában:

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

Példaként a GET következő üzenetet küldi https://jsonplaceholder.typicode.com/todos/3 ki a kérés:

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

HTTP Get from JSON

A https://jsonplaceholder.typicode.com/todos végpont "todo" objektumokból álló JSON-tömböt ad vissza. JSON-struktúrájuk a következőhöz hasonló:

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

A C# Todo objektum a következőképpen van definiálva:

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

Ez egy record class típus, választhatóId, Titleés CompletedUserId tulajdonságokkal rendelkezik. A típusról további információt a record C# rekordtípusainak bemutatása című témakörben talál. A kérések erős C# objektummá való automatikus deszerializálásához GET használja a GetFromJsonAsync System.Net.Http.Json NuGet-csomag részét képező bővítménymetódust.

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

A fenti kód a következőket végzi el:

  • A GET kérelem a (3) és a ( "https://jsonplaceholder.typicode.com/todos?userId=1&completed=false"3)
    • A lekérdezési sztring a kérelem szűrési feltételeit jelöli.
  • A rendszer automatikusan deszerializálja a választ, List<Todo> ha sikeres.
  • A kérés részletei a konzolra vannak írva, az egyes Todo objektumokkal együtt.

HTTP-bejegyzés

A POST kérelem adatokat küld a kiszolgálónak feldolgozás céljából. A Content-Type kérés fejléce azt jelzi, hogy milyen MIME-típust küld a törzs. HTTP-kérések POST létrehozásához adjon meg egy HttpClient és egy Urielemet, használja a HttpClient.PostAsync következő módszert:

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

A fenti kód a következőket végzi el:

  • Előkészít egy példányt StringContent a kérelem JSON-törzsével (MIME típusa "application/json").
  • Kérést küld a ()POST > számára "https://jsonplaceholder.typicode.com/todos".
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérés részleteit a konzolra.
  • A válasz törzsét sztringként írja a konzolra.

HTTP-közzététel JSON-ként

A kérésargumentumok automatikus szerializálásához POST és a válaszok erős C# típusú objektumokká való deszerializálásához használja a PostAsJsonAsync System.Net.Http.Json NuGet-csomag részét képező bővítménymetódust.

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

A fenti kód a következőket végzi el:

  • Szerializálja a Todo példányt JSON-ként, és kérést POST küld a következőre "https://jsonplaceholder.typicode.com/todos": .
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérés részleteit a konzolra.
  • Deszerializálja a válasz törzsét egy Todo példányba, és beírja a Todo konzolra.

HTTP-berakott

A PUT kérelemmetódus lecserél egy meglévő erőforrást, vagy létrehoz egy újat a kérelem törzsének hasznos adataival. HTTP-kérés PUT HttpClient és URI igényléséhez használja a HttpClient.PutAsync következő módszert:

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

A fenti kód a következőket végzi el:

  • Előkészít egy példányt StringContent a kérelem JSON-törzsével (MIME típusa "application/json").
  • Kérést küld a ()PUT > számára "https://jsonplaceholder.typicode.com/todos/1".
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérelem részleteit és a JSON válasz törzsét a konzolra.

HTTP JSON-ként való üzembe helyezve

A kérelemargumentumok automatikus szerializálásához PUT és a válaszok erős C#-objektumokba való deszerializálásához használja a PutAsJsonAsync System.Net.Http.Json NuGet-csomag részét képező bővítménymetódust.

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

A fenti kód a következőket végzi el:

  • Szerializálja a Todo példányt JSON-ként, és kérést PUT küld a következőre "https://jsonplaceholder.typicode.com/todos/5": .
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérés részleteit a konzolra.
  • Deszerializálja a válasz törzsét egy Todo példányba, és beírja a Todo konzolra.

HTTP-javítás

A PATCH kérés egy meglévő erőforrás részleges frissítése. Nem hoz létre új erőforrást, és nem egy meglévő erőforrás cseréjére szolgál. Ehelyett csak részben frissíti az erőforrást. HTTP-kérés PATCH HttpClient és URI igényléséhez használja a HttpClient.PatchAsync következő módszert:

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

A fenti kód a következőket végzi el:

  • Előkészít egy példányt StringContent a kérelem JSON-törzsével (MIME típusa "application/json").
  • Kérést küld a ()PATCH > számára "https://jsonplaceholder.typicode.com/todos/1".
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérelem részleteit és a JSON válasz törzsét a konzolra.

A NuGet-csomagban lévő System.Net.Http.Json kérésekhez nem léteznek PATCH bővítménymetelyek.

HTTP-törlés

A DELETE kérés töröl egy meglévő erőforrást. A DELETE kérések idempotensek , de nem biztonságosak, ami azt jelenti, hogy ugyanazon erőforrásokra irányuló több DELETE kérés ugyanazt az eredményt adja, de a kérés hatással van az erőforrás állapotára. HTTP-kérés DELETE HttpClient és URI igényléséhez használja a HttpClient.DeleteAsync következő módszert:

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

A fenti kód a következőket végzi el:

  • Kérést küld a ()DELETE > számára "https://jsonplaceholder.typicode.com/todos/1".
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérés részleteit a konzolra.

Tipp.

A kérésre DELETE adott válasz (csakúgy, mint egy PUT kérelem) tartalmazhat vagy nem tartalmazhat törzset.

HTTP-fej

A HEAD kérés hasonló a GET kéréshez. Az erőforrás visszaadása helyett csak az erőforráshoz társított fejléceket adja vissza. A kérésre HEAD adott válasz nem ad vissza törzset. HA HTTP-kérést HEAD szeretne küldeni egy HttpClient adott és egy URI-val, használja a HttpClient.SendAsync metódust a HttpMethod következő értékre 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
}

A fenti kód a következőket végzi el:

  • Kérést küld a ()HEAD > számára "https://www.example.com/".
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérés részleteit a konzolra.
  • Iterálja az összes válaszfejlécet, és mindegyiket a konzolra írja.

HTTP-beállítások

A OPTIONS kérés a kiszolgáló vagy végpont által támogatott HTTP-metódusok azonosítására szolgál. HA HTTP-kérést OPTIONS szeretne küldeni egy HttpClient adott és egy URI-val, használja a HttpClient.SendAsync metódust a HttpMethod következő értékre 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
}

A fenti kód a következőket végzi el:

  • HTTP-kérést küld a.a0>-nak"https://www.example.com/".
  • Biztosítja, hogy a válasz sikeres legyen, és megírja a kérés részleteit a konzolra.
  • Iterálja az összes választartalom fejlécét, és mindegyiket a konzolra írja.

HTTP-nyomkövetés

A TRACE kérés hasznos lehet a hibakereséshez, mivel alkalmazásszintű visszacsatolást biztosít a kérési üzenethez. HTTP-kérés TRACE létrehozásához hozzon létre egy következőtHttpMethod.TraceHttpRequestMessage:

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

Figyelemfelhívás

A TRACE HTTP-metódust nem támogatja az összes HTTP-kiszolgáló. Biztonsági rést tehet közzé, ha nem megfelelő módon használják. További információ: Open Web Application Security Project (OWASP): Cross Site Tracing.

HTTP-válasz kezelése

Amikor HTTP-választ kezel, a típust használja HttpResponseMessage . A válasz érvényességének kiértékeléséhez több tag is használható. A HTTP-állapotkód a HttpResponseMessage.StatusCode tulajdonságon keresztül érhető el. Tegyük fel, hogy egy ügyfélpéldányra vonatkozó kérést küldött:

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

Annak biztosítása érdekében, hogy az response állapot OK (HTTP-állapotkód 200) legyen, az alábbi példában látható módon értékelheti ki:

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

Vannak más HTTP-állapotkódok is, amelyek sikeres választ jelentenek, például CREATED (HTTP-állapotkód: 201), ACCEPTED (HTTP-állapotkód: 202), NO CONTENT (HTTP-állapotkód: 204) és RESET CONTENT (HTTP-állapotkód: 205). A tulajdonság segítségével ezeket a HttpResponseMessage.IsSuccessStatusCode kódokat is kiértékelheti, ami biztosítja, hogy a válasz állapotkódja a 200–299 tartományon belül legyen:

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

Ha a keretrendszert a következőre kell dobnia HttpRequestException, meghívhatja a metódust HttpResponseMessage.EnsureSuccessStatusCode() :

response.EnsureSuccessStatusCode();

Ez a kód akkor HttpRequestException jelenik meg, ha a válasz állapotkódja nem a 200–299 tartományon belül van.

ÉRVÉNYES HTTP-tartalomválaszok

Érvényes válasz esetén a tulajdonság használatával elérheti a válasz törzsét Content . A törzs példányként HttpContent érhető el, amellyel streamként, bájttömbként vagy sztringként érheti el a törzset:

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

Az előző kódban a responseStream válasz törzsének olvasására használható.

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

Az előző kódban a responseByteArray válasz törzsének olvasására használható.

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

Az előző kódban a responseString válasz törzsének olvasására használható.

Végül, ha tudja, hogy egy HTTP-végpont JSON-t ad vissza, a System.Net.Http.Json NuGet-csomag használatával deszerializálhatja a válasz törzsét bármely érvényes C#-objektumba:

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

Az előző kódban result a válasz törzse deszerializált típusként T.

HTTP-hibakezelés

Ha egy HTTP-kérés meghiúsul, a HttpRequestException parancs ki lesz dobva. Előfordulhat, hogy a kivétel önmagában nem elegendő, mivel más lehetséges kivételek is felmerülhetnek, amelyeket érdemes megfontolni. Előfordulhat például, hogy a hívó kód olyan lemondási jogkivonatot használt, amelyet a kérés befejezése előtt töröltek. Ebben a forgatókönyvben a következőt TaskCanceledExceptionfoghatja:

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

Hasonlóképpen, ha HTTP-kérést küld, ha a kiszolgáló nem válaszol a HttpClient.Timeout túllépés előtt, ugyanaz a kivétel lesz kivédve. Ebben a forgatókönyvben azonban megkülönböztetheti, hogy az időtúllépés történt, ha kiértékeli a Exception.InnerException következőt 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}");
}

Az előző kódban, amikor a belső kivétel TimeoutException az időtúllépés, és a kérést nem törölte a lemondási jogkivonat.

A HTTP-állapotkód kiértékeléséhez HttpRequestExceptiona következő tulajdonságot kell kiértékelnie 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}");
}

Az előző kódban a EnsureSuccessStatusCode() metódus kivételt jelez, ha a válasz nem sikeres. Ezt HttpRequestException.StatusCode követően a rendszer kiértékeli a tulajdonságot annak megállapítására, hogy a válasz (HTTP-állapotkód: 404) volt-e 404 . Az ön nevében implicit módon történő híváshoz HttpClient EnsureSuccessStatusCode számos segítő módszer létezik, vegye figyelembe a következő API-kat:

Tipp.

Minden HttpClient olyan HTTP-kérés készítésére használt módszer, amely nem ad vissza HttpResponseMessage implicit hívást EnsureSuccessStatusCode az Ön nevében.

A metódusok meghívásakor kezelheti és kiértékelheti a HttpRequestException tulajdonságot a HttpRequestException.StatusCode válasz HTTP-állapotkódjának meghatározásához:

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

Előfordulhatnak olyan helyzetek, amikor be kell dobnia a HttpRequestException kódot. A HttpRequestException() konstruktor nyilvános, és használatával kivételt vethet ki egy egyéni üzenettel:

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

A HTTP-proxyk kétféleképpen konfigurálhatók. A tulajdonságon HttpClient.DefaultProxy alapértelmezett érték van megadva. Másik lehetőségként megadhat egy proxyt a HttpClientHandler.Proxy tulajdonságon.

Globális alapértelmezett proxy

Ez HttpClient.DefaultProxy egy statikus tulajdonság, amely meghatározza az összes HttpClient példány által használt alapértelmezett proxyt, ha nincs explicit módon beállítva a HttpClientHandler konstruktor által átadott proxy.

A tulajdonság által visszaadott alapértelmezett példány a platformtól függően eltérő szabálykészletet követ:

  • Windows esetén: Beolvassa a proxykonfigurációt a környezeti változókból, vagy ha nincsenek definiálva, a felhasználó proxybeállításaiból.
  • MacOS esetén: Beolvassa a proxykonfigurációt a környezeti változókból, vagy ha nincsenek definiálva, a rendszer proxybeállításaiból.
  • Linux esetén: Beolvassa a proxykonfigurációt a környezeti változókból, vagy ha ezek nincsenek definiálva, ez a tulajdonság inicializál egy nem konfigurált példányt, amely minden címet átad.

A Windows- és Unix-alapú platformokon az inicializáláshoz DefaultProxy használt környezeti változók a következők:

  • HTTP_PROXY: a HTTP-kérelmekhez használt proxykiszolgáló.
  • HTTPS_PROXY: a HTTPS-kérelmekhez használt proxykiszolgáló.
  • ALL_PROXY: a HTTP- és/vagy HTTPS-kéréseken használt proxykiszolgáló, ha HTTP_PROXY és/vagy HTTPS_PROXY nincs meghatározva.
  • NO_PROXY: a proxyzásból kizárandó gazdagépnevek vesszővel tagolt listája. A csillagokat helyettesítő karakterek nem támogatják; használjon egy kezdő kódot, ha egy altartományt szeretne egyezni. Példák: NO_PROXY=.example.com (kezdő ponttal) egyezni www.example.comfog, de nem egyezik example.com. NO_PROXY=example.com (bevezető pont nélkül) nem egyezik www.example.com. Ezt a viselkedést a jövőben újra lehet majd áttekinteni, hogy jobban illeszkedjenek más ökoszisztémákhoz.

Azokban a rendszerekben, ahol a környezeti változók megkülönböztetik a kis- és nagybetűket, a változónevek kis- vagy nagybetűk lehetnek. Először a kisbetűs nevek lesznek bejelölve.

A proxykiszolgáló lehet egy állomásnév vagy IP-cím, amelyet opcionálisan kettőspont és portszám követ, vagy lehet EGY http URL-cím, amely opcionálisan tartalmaz egy felhasználónevet és jelszót a proxyhitelesítéshez. Az URL-címnek a következővel httpkell kezdődnie, nem https, és nem tartalmazhat szöveget a gazdagépnév, az IP-cím vagy a port után.

Proxy ügyfélenként

A HttpClientHandler.Proxy tulajdonság azonosítja az WebProxy internetes erőforrásokra irányuló kérelmek feldolgozásához használandó objektumot. Ha meg szeretné adni, hogy ne használjon proxyt, állítsa a Proxy tulajdonságot a metódus által visszaadott proxypéldányra GlobalProxySelection.GetEmptyWebProxy() .

A helyi számítógép- vagy alkalmazáskonfigurációs fájl megadhat egy alapértelmezett proxyt. Ha a proxytulajdonság meg van adva, akkor a Proxy tulajdonság proxybeállításai felülbírálják a helyi számítógép- vagy alkalmazáskonfigurációs fájlt, és a kezelő a megadott proxybeállításokat használja. Ha nincs megadva proxy egy konfigurációs fájlban, és a Proxy tulajdonság nincs meghatározva, a kezelő a helyi számítógéptől örökölt proxybeállításokat használja. Ha nincsenek proxybeállítások, a rendszer közvetlenül a kiszolgálónak küldi el a kérést.

Az HttpClientHandler osztály a proxy megkerülő listáját elemzi a helyi számítógép beállításaitól örökölt helyettesítő karakterekkel. Az osztály például a HttpClientHandler böngészők megkerülő "nt*" listáját elemzi a normál kifejezésként "nt.*". Így a proxy URL-címe http://nt.com megkerüli az HttpClientHandler osztályt.

Az HttpClientHandler osztály támogatja a helyi proxy megkerülését. Az osztály helyinek tekinti a célhelyet, ha az alábbi feltételek bármelyike teljesül:

  1. A cél egy egyszerű nevet tartalmaz (az URL-címben nincs pont).
  2. A cél egy visszacsatolási címet (Loopback vagy IPv6Loopback) tartalmaz, vagy a cél a helyi számítógéphez rendelt címet IPAddress tartalmaz.
  3. A céltartomány utótagja megegyezik a helyi számítógép tartomány utótagjával (DomainName).

A proxy konfigurálásával kapcsolatos további információkért lásd:

Lásd még