Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Важные API
Используйте HttpClient и остальную часть Windows. API пространства имен Web.Http для отправки и получения информации с помощью протоколов HTTP 2.0 и HTTP 1.1.
Tip
Приложения WinUI 3, предназначенные для .NET 6 или более поздней версии, также могут использовать System.Net.Http.HttpClient (.NET HttpClient). Он поддерживает IHttpClientFactory, токены отмены и современные асинхронные паттерны. Используйте Windows.Web.Http.HttpClient, если вам нужны специфические для WinRT возможности, такие как запросы на ввод учетных данных, управление файлами cookie через брокер WinRT или интеграция с сетевой изоляцией Windows. Для простых HTTP-запросов в приложении WinUI 3 на .NET элемент System.Net.Http.HttpClient часто оказывается более простым решением.
Обзор HttpClient и пространства имен Windows.Web.Http
Классы в пространстве имен Windows.Web.Http и связанных пространствах имен Windows.Web.Http.Headers и Windows.Web.Http.Filters предоставляют интерфейс программирования для приложений Windows, которые действуют как HTTP-клиент, чтобы выполнять базовые GET-запросы или реализовывать более сложные функции HTTP, перечисленные ниже.
Методы для общих команд (DELETE, GET, PUT и POST). Каждый из этих запросов отправляется как асинхронная операция.
Поддержка распространенных параметров и шаблонов проверки подлинности.
Доступ к сведениям о протоколе SSL для транспорта.
Возможность включать настраиваемые фильтры в расширенные приложения.
Возможность получения, задания и удаления файлов cookie.
Сведения о ходе выполнения HTTP-запроса, доступные в асинхронных методах.
Класс Windows.Web.Http.HttpRequestMessage представляет сообщение HTTP-запроса, отправляемое с помощью Windows.Web.Http.HttpClient. Класс Windows.Web.Http.HttpResponseMessage представляет сообщение HTTP-ответа, полученное в результате HTTP-запроса. HTTP-сообщения определяются в RFC 2616 IETF.
Пространство имен Windows.Web.Http представляет содержимое HTTP в виде тела сущности HTTP и заголовков, включая cookie. Содержимое HTTP может быть связано с HTTP-запросом или HTTP-ответом. Пространство имён Windows.Web.Http предоставляет несколько различных классов для представления HTTP-содержимого.
- HttpBufferContent. Содержимое в качестве буфера
- HttpFormUrlEncodedContent. Содержимое в виде кортежей «имя-значение», закодированное с использованием MIME-типа application/x-www-form-urlencoded
- HttpMultipartContent. Содержимое в форме MIME-типа multipart/*.
- HttpMultipartFormDataContent. Содержимое, закодированное в MIME-типе multipart/form-data.
- HttpStreamContent. Содержимое в виде потока (внутренний тип используется методом HTTP GET для получения данных и метода HTTP POST для отправки данных)
- HttpStringContent. Содержимое в виде строки.
- IHttpContent — базовый интерфейс для разработчиков для создания собственных объектов содержимого
Фрагмент кода в разделе "Отправка простого запроса GET по протоколу HTTP" использует класс HttpStringContent для представления ОТВЕТА HTTP из HTTP-запроса GET в виде строки.
Пространство имён Windows.Web.Http.Headers поддерживает создание заголовков HTTP и файлов cookie, которые затем связаны с объектами HttpRequestMessage и HttpResponseMessage как свойства.
Отправка простого запроса GET по протоколу HTTP
Как уже упоминалось ранее в этой статье, пространство имен Windows.Web.Http позволяет приложениям Windows отправлять запросы GET. В следующем фрагменте кода показано, как отправить GET-запрос к http://www.contoso.com с помощью класса Windows.Web.Http.HttpClient и класса Windows.Web.Http.HttpResponseMessage для чтения ответа на 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;
}
Отправка двоичных данных методом POST по протоколу HTTP
Приведенный ниже пример кода C++/WinRT иллюстрирует использование данных формы и запроса POST для отправки небольшого объема двоичных данных в виде файла на веб-сервер. Код использует класс HttpBufferContent для представления двоичных данных и класса HttpMultipartFormDataContent для представления данных формы с несколькими частями.
Note
Вызов get (как показано в приведенном ниже примере кода) не подходит для потока пользовательского интерфейса. Правильный метод, используемый в этом случае, см. в разделе параллелизм и асинхронные операции с 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;
}
Для POST содержимого фактического двоичного файла (а не явных двоичных данных, используемых выше), проще использовать объект HttpStreamContent . Создайте одну и в качестве аргумента в конструктор передайте значение, возвращаемое из вызова StorageFile.OpenReadAsync. Этот метод возвращает поток данных в двоичном файле.
Кроме того, если вы загружаете большой файл (размером более 10 МБ), мы рекомендуем использовать API Background Transfer среды выполнения Windows.
Отправка данных JSON по HTTP методом POST
В следующем примере в конечную точку записывается часть JSON, а затем записывается текст ответа.
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();
}
}
Исключения в Windows. Web.Http
Исключение возникает, если в конструктор объекта Windows.Foundation.Uri передается недопустимая строка универсального идентификатора ресурса (URI).
.NET: Тип Windows.Foundation.Uri отображается как System.Uri в C# и VB.
В C# и Visual Basic эту ошибку можно избежать с помощью класса System.Uri в .NET 4.5 и одного из методов System.Uri.TryCreate для проверки строки, полученной пользователем до создания URI.
В C++не существует метода для анализа строки в URI. Если приложение получает входные данные от пользователя для Windows. Foundation.Uri конструктор должен находиться в блоке try/catch. Если возникает исключение, приложение может уведомить пользователя и запросить новое имя узла.
Windows. Web.Http не имеет удобной функции. Поэтому приложению, использующему HttpClient и другие классы в этом пространстве имен, необходимо использовать значение HRESULT.
В приложениях с помощью C++/WinRT структура winrt::hresult_error представляет исключение, возникщее во время выполнения приложения. Функция winrt::hresult_error::code возвращает HRESULT, связанный с конкретным исключением. Функция winrt::hresult_error::message возвращает системную строку, связанную со значением HRESULT . Дополнительные сведения см. в разделе об обработке ошибок с помощью C++/WinRT
Возможные значения HRESULT перечислены в файле заголовка Winerror.h . Приложение может фильтровать определенные значения HRESULT , чтобы изменить поведение приложения в зависимости от причины исключения.
В приложениях, использующих .NET Framework 4.5 в C#, VB.NET, system.Exception представляет ошибку во время выполнения приложения при возникновении исключения. Свойство System.Exception.HResult возвращает HRESULT , назначенное конкретному исключению. Свойство System.Exception.Message возвращает сообщение, описывающее исключение.
C++/CX заменен C++/WinRT. Но в приложениях, использующих C++/CX, платформа::Exception представляет ошибку во время выполнения приложения при возникновении исключения. Свойство Platform::Exception::HResult возвращает HRESULT, присвоенный конкретному исключению. Свойство Platform::Exception::Message возвращает указанную системой строку, связанную со значением HRESULT .
Для большинства ошибок проверки параметров возвращаемое значение HRESULT — E_INVALIDARG. При некоторых недопустимых вызовах методов возвращаемое значение HRESULT равно E_ILLEGAL_METHOD_CALL.
Windows developer