Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
API Importanti
Usare HttpClient e il resto del Windows. API dello spazio dei nomi Web.Http per inviare e ricevere informazioni usando i protocolli HTTP 2.0 e HTTP 1.1.
Tip
Le app WinUI 3 destinate a .NET 6 o versioni successive possono anche usare System.Net.Http.HttpClient (il .NET HttpClient). Supporta IHttpClientFactory, token di annullamento e modelli asincroni moderni. Usare Windows.Web.Http.HttpClient quando sono necessarie funzionalità specifiche di WinRT, ad esempio richieste di credenziali, gestione dei cookie tramite il broker WinRT o integrazione con Windows isolamento di rete. Per le richieste HTTP semplici in un'app WinUI 3 .NET, System.Net.Http.HttpClient è spesso più semplice.
Panoramica di HttpClient e dello spazio dei nomi Windows.Web.Http
Le classi nello spazio dei nomi Windows.Web.Http e nei correlati spazi dei nomi Windows.Web.Http.Headers e Windows.Web.Http.Filters forniscono un'interfaccia di programmazione per le app di Windows che agiscono come client HTTP per eseguire richieste GET di base o implementare le funzionalità HTTP più avanzate elencate di seguito.
Metodi per verbi comuni (DELETE, GET, PUT e POST). Ognuna di queste richieste viene inviata come operazione asincrona.
Supporto per impostazioni e modelli di autenticazione comuni.
Accesso ai dettagli SSL (Secure Sockets Layer) sul trasporto.
Possibilità di includere filtri personalizzati nelle app avanzate.
Possibilità di ottenere, impostare ed eliminare cookie.
Informazioni sullo stato delle richieste HTTP disponibili nei metodi asincroni.
La classe Windows.Web.Http.HttpRequestMessage rappresenta un messaggio di richiesta HTTP inviato da Windows.Web.Http.HttpClient. La classe Windows.Web.Http.HttpResponseMessage rappresenta un messaggio di risposta HTTP ricevuto in risposta a una richiesta HTTP. I messaggi HTTP vengono definiti in RFC 2616 da IETF.
Lo spazio dei nomi Windows.Web.Http rappresenta il contenuto HTTP come corpo e intestazioni dell'entità HTTP, inclusi i cookie. Il contenuto HTTP può essere associato a una richiesta HTTP o a una risposta HTTP. Lo spazio dei nomi Windows.Web.Http fornisce diverse classi per rappresentare il contenuto HTTP.
- HttpBufferContent. Contenuto di buffer
- HttpFormUrlEncodedContent. Contenuto come nome e tuple di valori codificate con il tipo MIME application/x-www-form-urlencoded
- HttpMultipartContent. Contenuto sotto forma di tipo MIME multipart/* .
- HttpMultipartFormDataContent. Contenuto codificato come tipo MIME multipart/form-data .
- HttpStreamContent. Contenuto come flusso (il tipo interno viene usato dal metodo HTTP GET per ricevere dati e il metodo HTTP POST per caricare i dati)
- HttpStringContent. Contenuto come stringa.
- IHttpContent - Interfaccia di base che consente agli sviluppatori di creare oggetti contenuto personalizzati
Il frammento di codice nella sezione "Inviare una semplice richiesta GET su HTTP" usa la classe HttpStringContent per rappresentare la risposta HTTP da una richiesta HTTP GET come stringa.
Windows. Lo spazio dei nomi Web.Http.Headers supporta la creazione di intestazioni e cookie HTTP, che vengono quindi associati come proprietà agli oggetti HttpRequestMessage e HttpResponseMessage.
Inviare una semplice richiesta GET tramite HTTP
Come accennato in precedenza in questo articolo, il Windows. Lo spazio dei nomi Web.Http consente alle app Windows di inviare richieste GET. Il frammento di codice seguente illustra come inviare una richiesta GET a http://www.contoso.com usando il Windows. Classe Web.Http.HttpClient e Windows. Classe Web.Http.HttpResponseMessage per leggere la risposta dalla richiesta GET.
//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("http://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"http://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;
}
Inviare dati binari tramite HTTP
L'esempio di codice C++/WinRT riportato di seguito illustra l'uso di dati del modulo e una richiesta POST per inviare una piccola quantità di dati binari come caricamento di file in un server Web. Il codice usa la classe HttpBufferContent per rappresentare i dati binari e la classe HttpMultipartFormDataContent per rappresentare i dati del modulo in più parti.
Note
Invocare get (come mostrato nell'esempio di codice seguente) non è appropriato per un thread dell'interfaccia utente. Per la tecnica corretta da usare in questo caso, vedere Concorrenza e operazioni asincrone con C++/WinRT.
// 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;
}
Per PUBBLICARE il contenuto di un file binario effettivo (anziché i dati binari espliciti usati in precedenza), è più facile usare un oggetto HttpStreamContent . Crearne uno e, come argomento per il relativo costruttore, passare il valore restituito da una chiamata a StorageFile.OpenReadAsync. Questo metodo restituisce un flusso per i dati all'interno del file binario.
Inoltre, se si carica un file di grandi dimensioni (di dimensioni superiori a circa 10 MB), è consigliabile usare le API di trasferimento in background Windows Runtime.
POST JSON data over HTTP
L'esempio seguente invia codice JSON a un endpoint e quindi scrive il corpo della risposta.
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();
}
}
Eccezioni in Windows.Web.Http
Viene generata un'eccezione quando viene passata una stringa non valida per un URI (Uniform Resource Identifier) al costruttore per il Windows. Oggetto Foundation.Uri.
.NET: Il tipo Windows.Foundation.Uri viene visualizzato come System.Uri in C# e VB.
In C# e Visual Basic questo errore può essere evitato usando la classe System.Uri nella .NET 4.5 e uno dei metodi System.Uri.TryCreate per testare la stringa ricevuta da un utente prima che venga costruito l'URI.
In C++, non esiste alcun metodo per provare e analizzare una stringa in un URI. Se un'app ottiene l'input dall'utente per il Windows. Foundation.Uri, il costruttore deve trovarsi in un blocco try/catch. Se viene generata un'eccezione, l'app può inviare una notifica all'utente e richiedere un nuovo nome host.
Windows. Web.Http non dispone di una funzione di praticità. Un'app che usa HttpClient e altre classi in questo spazio dei nomi deve quindi usare il valore HRESULT .
Nelle app che usano C++/WinRT, lo struct winrt::hresult_error rappresenta un'eccezione generata durante l'esecuzione dell'app. La funzione winrt::hresult_error::code restituisce il valore HRESULT assegnato all'eccezione specifica. La funzione winrt::hresult_error::message restituisce la stringa fornita dal sistema associata al valore HRESULT . Per altre info, vedi Gestione degli errori con C++/WinRT
I possibili valori HRESULT sono elencati nel file di intestazione Winerror.h . L'app può filtrare in base a valori HRESULT specifici per modificare il comportamento dell'app a seconda della causa dell'eccezione.
Nelle app che usano .NET Framework 4.5 in C#, VB.NET, System.Exception rappresenta un errore durante l'esecuzione dell'app quando si verifica un'eccezione. La proprietà System.Exception.HResult restituisce il valore HRESULT assegnato all'eccezione specifica. La proprietà System.Exception.Message restituisce il messaggio che descrive l'eccezione.
C++/CX è stato sostituito da C++/WinRT. Tuttavia, nelle app che usano C++/CX, Platform::Exception rappresenta un errore durante l'esecuzione dell'app quando si verifica un'eccezione. La proprietà Platform::Exception::HResult restituisce il valore HRESULT assegnato all'eccezione specifica. La proprietà Platform::Exception::Message restituisce la stringa fornita dal sistema associata al valore HRESULT .
Per la maggior parte degli errori di convalida dei parametri, il valore HRESULT restituito è E_INVALIDARG. Per alcune chiamate di metodo non valide, il valore HRESULT restituito è E_ILLEGAL_METHOD_CALL.