Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Важные 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