Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Fontos API-k
Használja a HttpClient és a többi Windows. Web.Http névtér API a HTTP 2.0 és HTTP 1.1 protokollok használatával történő információk küldéséhez és fogadásához.
Tip
A .NET 6-ot vagy újabbat célzó WinUI 3-alkalmazások a System.Net.Http.HttpClient elemet is használhatják (a .NET HttpClientet). Támogatja a IHttpClientFactory, megszakítási tokeneket és a modern aszinkron mintákat. Akkor használhatóWindows.Web.Http.HttpClient, ha WinRT-specifikus funkciókra, például hitelesítő adatokra vonatkozó kérésekre, a WinRT-közvetítőn keresztüli cookie-kezelésre vagy Windows hálózatelkülönítéssel való integrációra van szüksége. A .NET WinUI 3-alkalmazások System.Net.Http.HttpClient egyszerű HTTP-kérései gyakran egyszerűbbek.
A HttpClient és a Windows.Web.Http névtér áttekintése
A Windows osztályai. Web.Http névtér és a kapcsolódó Windows. Web.Http.Headers és Windows. A Web.Http.Filters névterek olyan programozási felületet biztosítanak Windows alkalmazások számára, amelyek HTTP-ügyfélként működnek az alapszintű GET-kérések végrehajtásához vagy az alább felsorolt fejlettebb HTTP-funkciók implementálásához.
Gyakori igék (DELETE, GET, PUT és POST) metódusai. Ezek a kérések mindegyike aszinkron műveletként lesz elküldve.
A gyakori hitelesítési beállítások és minták támogatása.
Hozzáférés a Secure Sockets Layer (SSL) adataihoz az átvitelen.
Testre szabott szűrők belefoglalása speciális alkalmazásokba.
A cookie-k lekérésének, beállításának és törlésének képessége.
AZ aszinkron metódusokon elérhető HTTP-kérések állapotinformációi.
A Windows.Web.Http.HttpRequestMessage osztály a Windows.Web.Http.HttpClient által küldött HTTP-kérési üzenetet reprezentálja. A Windows. A Web.Http.HttpResponseMessage osztály egy HTTP-kéréstől kapott HTTP-válaszüzenetet jelöl. A HTTP-üzeneteket az IETF határozza meg az RFC 2616-ban .
A Windows. A Web.Http névtér a HTTP-tartalmat jelöli a HTTP-entitás törzseként és fejléceiként, beleértve a cookie-kat is. A HTTP-tartalom HTTP-kéréshez vagy HTTP-válaszhoz társítható. A Windows. A Web.Http névtér számos különböző osztályt biztosít a HTTP-tartalom megjelenítéséhez.
- HttpBufferContent. Tartalom pufferként
- HttpFormUrlEncodedContent. A tartalom név- és értékpárokként van kódolva az application/x-www-form-urlencoded MIME-típussal
- HttpMultipartContent. Többrészes/* MIME típusú tartalom.
- HttpMultipartFormDataContent. Többrészes/űrlap-adat TÍPUSÚ MIME-típusként kódolt tartalom.
- HttpStreamContent. Tartalom streamként (a belső típust a HTTP GET metódus használja az adatok fogadásához, és a HTTP POST metódust az adatok feltöltéséhez)
- HttpStringContent. A tartalom karakterláncként.
- IHttpContent – Alapfelület a fejlesztők számára saját tartalomobjektumok létrehozásához
Az "Egyszerű GET kérés küldése HTTP-n keresztül" szakasz kódrészlete a HttpStringContent osztályt használja a HTTP GET-kérés HTTP-válaszának sztringként való megjelenítéséhez.
A Windows. A Web.Http.Headers névtér támogatja a HTTP-fejlécek és a cookie-k létrehozását, amelyek ezután a HttpRequestMessage és a HttpResponseMessage objektum tulajdonságaiként vannak társítva.
Egyszerű GET-kérés küldése HTTP-en keresztül
Ahogy a cikkben korábban említettük, a Windows. A Web.Http névtér lehetővé teszi, hogy Windows alkalmazások GET-kéréseket küldjenek. Az alábbi kódrészlet bemutatja, hogyan küldhet GET-kérést a(z) http://www.contoso.com címre a Windows.Web.Http.HttpClient osztály használatával, és hogyan olvashatja be a GET-kérés válaszát a Windows.Web.Http.HttpResponseMessage osztály használatával.
//Create an HTTP client object
Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
//Add a user-agent header to the GET request.
var headers = httpClient.DefaultRequestHeaders;
//The safe way to add a header value is to use the TryParseAdd method and verify the return value is true,
//especially if the header value is coming from user input.
string header = "MyApp/1.0";
if (!headers.UserAgent.TryParseAdd(header))
{
throw new Exception("Invalid header value: " + header);
}
Uri requestUri = new Uri("https://www.contoso.com");
//Send the GET request asynchronously and retrieve the response as a string.
Windows.Web.Http.HttpResponseMessage httpResponse = new Windows.Web.Http.HttpResponseMessage();
string httpResponseBody = "";
try
{
//Send the GET request
httpResponse = await httpClient.GetAsync(requestUri);
httpResponse.EnsureSuccessStatusCode();
httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message;
}
// pch.h
#pragma once
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Web.Http.Headers.h>
// main.cpp : Defines the entry point for the console application.
#include "pch.h"
#include <iostream>
using namespace winrt;
using namespace Windows::Foundation;
int main()
{
init_apartment();
// Create an HttpClient object.
Windows::Web::Http::HttpClient httpClient;
// Add a user-agent header to the GET request.
auto headers{ httpClient.DefaultRequestHeaders() };
// The safe way to add a header value is to use the TryParseAdd method, and verify the return value is true.
// This is especially important if the header value is coming from user input.
std::wstring header{ L"MyApp/1.0" };
if (!headers.UserAgent().TryParseAdd(header))
{
throw L"Invalid header value: " + header;
}
Uri requestUri{ L"https://www.contoso.com" };
// Send the GET request asynchronously, and retrieve the response as a string.
Windows::Web::Http::HttpResponseMessage httpResponseMessage;
std::wstring httpResponseBody;
try
{
// Send the GET request.
httpResponseMessage = httpClient.GetAsync(requestUri).get();
httpResponseMessage.EnsureSuccessStatusCode();
httpResponseBody = httpResponseMessage.Content().ReadAsStringAsync().get();
}
catch (winrt::hresult_error const& ex)
{
httpResponseBody = ex.message();
}
std::wcout << httpResponseBody;
}
POST bináris adatok HTTP-en keresztül
Az alábbi C++/WinRT-kódpéldában az űrlapadatok és a POST-kérések segítségével kis mennyiségű bináris adatot küldhet el fájlfeltöltésként egy webkiszolgálóra. A kód a HttpBufferContent osztályt használja a bináris adatok, a HttpMultipartFormDataContent osztály pedig a többrészes űrlapadatok megjelenítésére.
Note
A get hívása (ahogy az alábbi kód példában látható) nem megfelelő felhasználói felületi szálhoz. Az ebben az esetben használni kívánt helyes technikát lásd: Egyidejűség és aszinkron műveletek a C++/WinRT használatával.
// pch.h
#pragma once
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Security.Cryptography.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Web.Http.Headers.h>
// main.cpp : Defines the entry point for the console application.
#include "pch.h"
#include <iostream>
#include <sstream>
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;
int main()
{
init_apartment();
auto buffer{
Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary(
L"A sentence of text to encode into binary to serve as sample data.",
Windows::Security::Cryptography::BinaryStringEncoding::Utf8
)
};
Windows::Web::Http::HttpBufferContent binaryContent{ buffer };
// You can use the 'image/jpeg' content type to represent any binary data;
// it's not necessarily an image file.
binaryContent.Headers().Append(L"Content-Type", L"image/jpeg");
Windows::Web::Http::Headers::HttpContentDispositionHeaderValue disposition{ L"form-data" };
binaryContent.Headers().ContentDisposition(disposition);
// The 'name' directive contains the name of the form field representing the data.
disposition.Name(L"fileForUpload");
// Here, the 'filename' directive is used to indicate to the server a file name
// to use to save the uploaded data.
disposition.FileName(L"file.dat");
Windows::Web::Http::HttpMultipartFormDataContent postContent;
postContent.Add(binaryContent); // Add the binary data content as a part of the form data content.
// Send the POST request asynchronously, and retrieve the response as a string.
Windows::Web::Http::HttpResponseMessage httpResponseMessage;
std::wstring httpResponseBody;
try
{
// Send the POST request.
Uri requestUri{ L"https://www.contoso.com/post" };
Windows::Web::Http::HttpClient httpClient;
httpResponseMessage = httpClient.PostAsync(requestUri, postContent).get();
httpResponseMessage.EnsureSuccessStatusCode();
httpResponseBody = httpResponseMessage.Content().ReadAsStringAsync().get();
}
catch (winrt::hresult_error const& ex)
{
httpResponseBody = ex.message();
}
std::wcout << httpResponseBody;
}
Ha közzé szeretné tenni egy tényleges bináris fájl tartalmát (a fent használt explicit bináris adatok helyett), könnyebben használhat httpStreamContent objektumot. Hozzon létre egyet, és a konstruktor argumentumaként adja át a StorageFile.OpenReadAsync hívásból visszaadott értéket. Ez a metódus egy adatfolyamot ad vissza a bináris fájlban lévő adatokhoz.
Emellett, ha nagy fájlt tölt fel (körülbelül 10 MB-nál nagyobb), akkor javasoljuk, hogy használja a Windows-futtatókörnyezet háttérátviteli API-kat.
JSON-adatok KÖZZÉTÉTELE HTTP-en keresztül
Az alábbi példa közzéten néhány JSON-t egy végponton, majd kiírja a válasz törzsét.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Web.Http;
private async Task TryPostJsonAsync()
{
try
{
// Construct the HttpClient and Uri. This endpoint is for test purposes only.
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("https://www.contoso.com/post");
// Construct the JSON to post.
HttpStringContent content = new HttpStringContent(
"{ \"firstName\": \"Eliot\" }",
UnicodeEncoding.Utf8,
"application/json");
// Post the JSON and wait for a response.
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(
uri,
content);
// Make sure the post succeeded, and write out the response.
httpResponseMessage.EnsureSuccessStatusCode();
var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
Debug.WriteLine(httpResponseBody);
}
catch (Exception ex)
{
// Write out any exceptions.
Debug.WriteLine(ex);
}
}
// pch.h
#pragma once
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Security.Cryptography.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Web.Http.Headers.h>
// main.cpp : Defines the entry point for the console application.
#include "pch.h"
#include <iostream>
#include <sstream>
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;
int main()
{
init_apartment();
Windows::Web::Http::HttpResponseMessage httpResponseMessage;
std::wstring httpResponseBody;
try
{
// Construct the HttpClient and Uri. This endpoint is for test purposes only.
Windows::Web::Http::HttpClient httpClient;
Uri requestUri{ L"https://www.contoso.com/post" };
// Construct the JSON to post.
Windows::Web::Http::HttpStringContent jsonContent(
L"{ \"firstName\": \"Eliot\" }",
UnicodeEncoding::Utf8,
L"application/json");
// Post the JSON, and wait for a response.
httpResponseMessage = httpClient.PostAsync(
requestUri,
jsonContent).get();
// Make sure the post succeeded, and write out the response.
httpResponseMessage.EnsureSuccessStatusCode();
httpResponseBody = httpResponseMessage.Content().ReadAsStringAsync().get();
std::wcout << httpResponseBody.c_str();
}
catch (winrt::hresult_error const& ex)
{
std::wcout << ex.message().c_str();
}
}
Hibák kezelése
A HttpClient használatával végrehajtott hívások két különböző módon meghiúsulhatnak, és mindegyik másképpen kezelhető.
- A kiszolgáló hibaállapot-kóddal válaszol. A kérés befejeződik, de a kiszolgáló egy 4xx vagy 5xx állapotkódot ad vissza (például: 404 Nem található vagy 503 Szolgáltatás nem érhető el). Ez nem ad kivételt. A
GetAsyncvagyPostAsynchívás normálisan egy HttpResponseMessage objektummal tér vissza, amelynek IsSuccessStatusCode tulajdonságafalse. - A kérés a válasz beérkezése előtt meghiúsul. A kliens egyáltalán nem tudja befejezni a kommunikációt (például nincs hálózati kapcsolat, a gazdagép neve nem oldható fel, a kapcsolat időtúllépéssel megszakad, vagy a TLS-tárgyalás meghiúsul). Ez kivételt eredményez.
Mivel a visszaadott hibaállapotkód nem jelenik meg, csak a kivételek ellenőrzése nem elegendő. Vizsgálja meg a választ , és észlelje a kivételeket.
A válasz állapotkódjának ellenőrzése
Olvassa el a HttpResponseMessage.IsSuccessStatusCode című cikket annak ellenőrzéséhez, hogy a kiszolgáló sikeres (2xx) kódot adott-e vissza. Az adott kód ágazásához olvassa el a HttpResponseMessage.StatusCode ( httpStatusCode-érték ) és a ReasonPhrase parancsot.
Az EnsureSuccessStatusCode meghívása, ahogy a korábbi példákban is, egy rövidebb megoldás: kivételt dob, ha az állapotkód nem sikeres, így mindkét hibamódot egyetlen catch blokkban kezelheti. Csak akkor hívja meg, ha azt szeretné, hogy egy nem sikeres kód hibaként legyen kezelve. Ha egy 4xx vagy 5xx válasz választörzsét szeretné elolvasni, ellenőrizze IsSuccessStatusCode helyette.
Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
Uri requestUri = new Uri("https://www.contoso.com");
Windows.Web.Http.HttpResponseMessage response = await httpClient.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
string body = await response.Content.ReadAsStringAsync();
// Process the successful response.
}
else
{
// The server responded, but with an error status code.
System.Diagnostics.Debug.WriteLine($"Request failed: {(int)response.StatusCode} {response.StatusCode} ({response.ReasonPhrase})");
}
Hálózati kivétel besorolása
Ha egy kérés a válasz fogadása előtt érkezik (például a név nem oldható fel, vagy a kapcsolat meghiúsul vagy túllépi az időkorlátot), a kivétel azonosítja HResult a mögöttes hálózati hibát. Adja át a Windows.Web.WebError.GetStatus metódusnak, hogy egy WebErrorStatus értéket kapjon, amely leírja az okot (például HostNameNotResolved, CannotConnect, Timeout vagy ConnectionReset). Ezzel eldöntheti, hogy értesíti a felhasználót, visszaesik vagy újra próbálkozik.
WebError.GetStatus nem vonatkozik a HTTP-hibaválaszokra (4xx vagy 5xx állapotkódok), mert a kiszolgáló válaszolt. Ellenőrizze a HttpResponseMessage.IsSuccessStatusCode vagy a HttpResponseMessage.StatusCode értékét ezek kezeléséhez a(z) EnsureSuccessStatusCode meghívása helyett.
Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient();
Uri requestUri = new Uri("https://www.contoso.com");
try
{
Windows.Web.Http.HttpResponseMessage response = await httpClient.GetAsync(requestUri);
if (!response.IsSuccessStatusCode)
{
// Handle the non-success HTTP status code (for example, 404 Not Found or 503 Service Unavailable).
System.Diagnostics.Debug.WriteLine($"HTTP error: {(int)response.StatusCode} {response.StatusCode}");
return;
}
string body = await response.Content.ReadAsStringAsync();
// Process the successful response.
}
catch (Exception ex)
{
Windows.Web.WebErrorStatus status = Windows.Web.WebError.GetStatus(ex.HResult);
switch (status)
{
case Windows.Web.WebErrorStatus.HostNameNotResolved:
case Windows.Web.WebErrorStatus.CannotConnect:
case Windows.Web.WebErrorStatus.Timeout:
case Windows.Web.WebErrorStatus.ConnectionReset:
// A transient connectivity problem. Retrying with backoff may succeed.
System.Diagnostics.Debug.WriteLine($"Network error: {status}.");
break;
case Windows.Web.WebErrorStatus.Unknown:
// GetStatus couldn't map the HRESULT to a WebErrorStatus value.
System.Diagnostics.Debug.WriteLine($"Unmapped error. HRESULT: 0x{ex.HResult:X8} {ex.Message}");
break;
default:
System.Diagnostics.Debug.WriteLine($"Web error: {status}");
break;
}
}
Ugyanez a minta a C++/WinRT-ben is érvényes, és a winrt::hresult_error::code értéket használja a bemenetként GetStatus.
// #include <winrt/Windows.Web.h>
try
{
auto response{ httpClient.GetAsync(requestUri).get() };
if (!response.IsSuccessStatusCode())
{
// Handle the non-success HTTP status code (for example, 404 Not Found or 503 Service Unavailable).
}
else
{
auto body{ response.Content().ReadAsStringAsync().get() };
// Process the successful response.
}
}
catch (winrt::hresult_error const& ex)
{
Windows::Web::WebErrorStatus status{ Windows::Web::WebError::GetStatus(ex.code()) };
if (status == Windows::Web::WebErrorStatus::HostNameNotResolved ||
status == Windows::Web::WebErrorStatus::CannotConnect ||
status == Windows::Web::WebErrorStatus::Timeout ||
status == Windows::Web::WebErrorStatus::ConnectionReset)
{
// A transient connectivity problem. Retrying with backoff may succeed.
}
else
{
// Inspect status, or fall back to ex.code() and ex.message().
}
}
Átmeneti hibák esetén újrapróbálkozás
A HttpClient nem próbálkozik újra a sikertelen kérésekkel. Átmeneti hibák esetén (a fent bemutatott kapcsolódási hibák, illetve az olyan szerver-válaszkódok esetén, mint a 429 Túl sok kérés, az 503 A szolgáltatás nem érhető el és az 504 Átjáró időtúllépése) próbálja újra a kérést exponenciális visszavárakozással, és vegye figyelembe a Retry-After válaszfejlécet, amikor a szerver ilyet küld. Korlátozza az újrapróbálkozások számát, és ne próbálkozzon újra nem átmeneti jellegű hibák, például 400 Bad Request vagy 404 Not Found esetén.
A Windows.Web.Http kivételei
A rendszer kivételt ad, ha érvénytelen egységes erőforrás-azonosító (URI) karakterláncot adnak át a Windows.Foundation.Uri objektum konstruktorának.
.NET: A Windows. A Foundation.Uri típus System.Uri formátumban jelenik meg c# és VB nyelven.
C# és Visual Basic esetén ez a hiba elkerülhető a System.Uri osztály .NET 4.5 és a System.Uri.TryCreate metódusok egyikével a felhasználótól kapott sztring teszteléséhez az URI létrehozása előtt.
A C++-ban nincs olyan metódus, amellyel meg lehetne próbálni egy karakterláncot URI-ként értelmezni. Ha egy alkalmazás a felhasználótól kapott bemenetet használja a Windows.Foundation.Uri számára, a konstruktort try/catch blokkba kell helyezni. Kivétel esetén az alkalmazás értesítheti a felhasználót, és új állomásnevet kérhet.
A Windows. A Web.Http nem rendelkezik kényelmi funkcióval. Ezért a HttpClient-et és a névtér más osztályát használó alkalmazásoknak a HRESULT értéket kell használniuk.
A C++/WinRT-t használó alkalmazásokban a winrt::hresult_error szerkezet az alkalmazás végrehajtása során felmerülő kivételt jelöli. A winrt::hresult_error::code függvény az adott kivételhez rendelt HRESULT értéket adja vissza. A winrt::hresult_error::message függvény a HRESULT értékhez társított rendszer által biztosított sztringet adja vissza. További információ: Hibakezelés a C++/WinRT használatával
A lehetséges HRESULT értékek a Winerror.h fejlécfájlban vannak felsorolva. Az alkalmazás a kivétel okától függően szűrhet bizonyos HRESULT-értékeket az alkalmazás viselkedésének módosításához.
A C#-ban és a VB.NET-ben a .NET Framework 4.5-öt használó alkalmazásokban a System.Exception az alkalmazás futása során fellépő hibát jelöli, amikor kivétel történik. A System.Exception.HResult tulajdonság az adott kivételhez rendelt HRESULT értéket adja vissza. A System.Exception.Message tulajdonság a kivételt leíró üzenetet adja vissza.
A C++/CX helyébe a C++/WinRT lépett. A C++/CX-et használó alkalmazásokban azonban a Platform::Kivétel egy hiba az alkalmazás végrehajtása során, amikor kivétel történik. A Platform::Exception::HResult tulajdonság az adott kivételhez rendelt HRESULT értéket adja vissza. A Platform::Exception::Message tulajdonság a HRESULT értékhez társított rendszer által biztosított sztringet adja vissza.
A legtöbb paraméterérvényesítési hiba esetén a visszaadott HRESULT értéke E_INVALIDARG. Néhány nem engedélyezett metódushívás esetén a visszaadott HRESULT értéke E_ILLEGAL_METHOD_CALL.
Kapcsolódó témakörök
Windows developer