Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
API Penting
Gunakan HttpClient serta API lainnya dalam namespace Windows.Web.Http untuk mengirim dan menerima informasi menggunakan protokol HTTP 2.0 dan HTTP 1.1.
Tip
Aplikasi WinUI 3 yang menargetkan .NET 6 atau yang lebih baru juga dapat menggunakan System.Net.Http.HttpClient (.NET HttpClient). Ini mendukung IHttpClientFactory, token pembatalan, dan pola asinkron modern. Gunakan Windows.Web.Http.HttpClient saat Anda memerlukan fitur khusus WinRT seperti perintah kredensial, manajemen cookie melalui broker WinRT, atau integrasi dengan isolasi jaringan Windows. Untuk permintaan HTTP langsung dalam aplikasi .NET WinUI 3, System.Net.Http.HttpClient sering kali lebih sederhana.
Gambaran umum tentang HttpClient dan namespace Windows.Web.Http
Kelas dalam namespace Windows.Web.Http serta namespace terkait Windows.Web.Http.Headers dan Windows.Web.Http.Filters menyediakan antarmuka pemrograman untuk aplikasi Windows yang bertindak sebagai klien HTTP guna melakukan permintaan GET dasar atau mengimplementasikan fungsionalitas HTTP yang lebih canggih seperti yang tercantum di bawah ini.
Metode untuk kata kerja umum (DELETE, GET, PUT, dan POST). Masing-masing permintaan ini dikirim sebagai operasi asinkron.
Dukungan untuk pengaturan dan pola autentikasi umum.
Akses ke detail Secure Sockets Layer (SSL) pada transpor.
Kemampuan untuk menyertakan filter yang disesuaikan dalam aplikasi tingkat lanjut.
Kemampuan untuk mendapatkan, mengatur, dan menghapus cookie.
Info kemajuan Permintaan HTTP tersedia pada metode asinkron.
Kelas Windows.Web.Http.HttpRequestMessage merepresentasikan pesan permintaan HTTP yang dikirim oleh Windows.Web.Http.HttpClient. Kelas Windows.Web.Http.HttpResponseMessage merepresentasikan pesan respons HTTP yang diterima dari permintaan HTTP. Pesan HTTP didefinisikan dalam RFC 2616 oleh IETF.
Namespace Windows.Web.Http merepresentasikan konten HTTP sebagai isi entitas dan header HTTP, termasuk cookie. Konten HTTP dapat dikaitkan dengan permintaan HTTP atau respons HTTP. Namespace Windows.Web.Http menyediakan sejumlah kelas untuk merepresentasikan konten HTTP.
- HttpBufferContent. Konten sebagai buffer
- HttpFormUrlEncodedContent. Konten sebagai pasangan nama dan nilai yang dikodekan dengan tipe MIME application/x-www-form-urlencoded
- HttpMultipartContent. Konten dalam bentuk jenis MIME multipart/* .
- HttpMultipartFormDataContent. Konten yang dikodekan sebagai jenis MIME multipart/form-data .
- HttpStreamContent. Konten sebagai aliran (jenis internal digunakan oleh metode HTTP GET untuk menerima data dan metode HTTP POST untuk mengunggah data)
- HttpStringContent. Konten dalam bentuk string.
- IHttpContent - Antarmuka dasar bagi pengembang untuk membuat objek konten mereka sendiri
Cuplikan kode di bagian "Kirim permintaan GET sederhana melalui HTTP" menggunakan kelas HttpStringContent untuk mewakili respons HTTP dari permintaan HTTP GET sebagai string.
Windows. Namespace layanan Web.Http.Headers mendukung pembuatan header HTTP dan cookie, yang kemudian dikaitkan sebagai properti dengan objek HttpRequestMessage dan HttpResponseMessage.
Mengirim permintaan GET sederhana melalui HTTP
Seperti disebutkan sebelumnya dalam artikel ini, Windows. Namespace Web.Http memungkinkan aplikasi Windows mengirim permintaan GET. Cuplikan kode berikut menunjukkan cara mengirim permintaan GET untuk http://www.contoso.com menggunakan Windows. Kelas Web.Http.HttpClient dan Windows. Kelas Web.Http.HttpResponseMessage untuk membaca respons dari permintaan 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("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 data biner melalui HTTP
Contoh kode C++/WinRT di bawah ini menggambarkan menggunakan data formulir dan permintaan POST untuk mengirim sejumlah kecil data biner sebagai unggahan file ke server web. Kode menggunakan kelas HttpBufferContent untuk mewakili data biner, dan kelas HttpMultipartFormDataContent untuk mewakili data formulir multi-bagian.
Note
Memanggil get (seperti yang terlihat dalam contoh kode di bawah) tidak sesuai untuk utas UI. Untuk teknik yang tepat digunakan dalam kasus tersebut, lihat Konkurensi dan operasi asinkron dengan 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;
}
Untuk MEMPOSTING konten file biner aktual (daripada data biner eksplisit yang digunakan di atas), Anda akan merasa lebih mudah untuk menggunakan objek HttpStreamContent . Buat satu dan, sebagai argumen ke konstruktornya, teruskan nilai yang dikembalikan dari panggilan ke StorageFile.OpenReadAsync. Metode tersebut mengembalikan aliran untuk data di dalam file biner Anda.
Selain itu, jika Anda mengunggah file besar (lebih besar dari sekitar 10MB), kami sarankan Anda menggunakan API Transfer Latar Belakang Windows Runtime.
Kirim data JSON melalui HTTP dengan metode POST
Contoh berikut memposting beberapa JSON ke titik akhir, lalu menulis isi respons.
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();
}
}
Menangani kesalahan
Panggilan yang dilakukan dengan HttpClient dapat gagal dengan dua cara yang berbeda, dan Anda menangani masing-masing secara berbeda.
- Server merespons dengan kode status kesalahan. Permintaan selesai, tetapi server mengembalikan kode status 4xx atau 5xx (misalnya, 404 Tidak Ditemukan atau 503 Layanan Tidak Tersedia). Ini tidak memunculkan pengecualian. Panggilan
GetAsyncatauPostAsynckembali secara normal dengan HttpResponseMessage yang properti IsSuccessStatusCode-nya adalahfalse. - Permintaan gagal sebelum respons diterima. Klien tidak dapat menyelesaikan pertukaran sama sekali (misalnya, tidak ada koneksi jaringan, nama host tidak menyelesaikan, waktu koneksi habis, atau negosiasi TLS gagal). Ini memunculkan pengecualian.
Karena kode status kesalahan yang dikembalikan tidak ditampilkan, hanya memeriksa pengecualian tidak cukup. Periksa respons dan tangkap pengecualian.
Periksa kode status respons
Baca HttpResponseMessage.IsSuccessStatusCode untuk menguji apakah server mengembalikan kode sukses (2xx). Untuk bercabang pada kode tertentu, baca HttpResponseMessage.StatusCode (nilai HttpStatusCode ) dan ReasonPhrase.
Memanggil EnsureSuccessStatusCode, seperti contoh sebelumnya, adalah pintasan yang melemparkan pengecualian ketika kode status bukan kode keberhasilan, sehingga Anda dapat menangani kedua mode kegagalan dalam satu catch blok. Panggil ini hanya jika Anda ingin kode nonkeberhasilan dianggap sebagai error. Jika Anda ingin membaca isi respons balasan 4xx atau 5xx, periksa IsSuccessStatusCode sebagai gantinya.
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})");
}
Mengklasifikasikan pengecualian jaringan
Ketika permintaan dilemparkan sebelum respons diterima (misalnya, nama tidak dapat diselesaikan, atau koneksi gagal atau kehabisan waktu), pengecualian HResult mengidentifikasi kesalahan jaringan yang mendasar. Berikan ke Windows. Web.WebError.GetStatus untuk mendapatkan nilai WebErrorStatus yang menjelaskan penyebabnya (misalnya, HostNameNotResolved, , CannotConnectTimeout, atau ConnectionReset). Gunakan untuk memutuskan apakah akan memberi tahu pengguna, mundur, atau mencoba kembali.
WebError.GetStatus tidak berlaku untuk respons kesalahan HTTP (kode status 4xx atau 5xx), karena server merespons. Periksa HttpResponseMessage.IsSuccessStatusCode atau HttpResponseMessage.StatusCode untuk menanganinya alih-alih memanggil EnsureSuccessStatusCode.
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;
}
}
Pola yang sama berlaku di C++/WinRT, menggunakan winrt::hresult_error::code sebagai input ke 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().
}
}
Coba lagi jika terjadi kegagalan sementara
HttpClient tidak mencoba kembali permintaan yang gagal untuk Anda. Untuk kegagalan sementara (kesalahan konektivitas yang ditunjukkan di atas, atau kode server seperti 429 Too Many Requests, 503 Service Unavailable, dan 504 Gateway Timeout), coba lagi permintaan tersebut sendiri dengan menggunakan penundaan eksponensial, dan patuhi header respons Retry-After saat server mengirimkannya. Batasi jumlah upaya, dan jangan coba lagi kesalahan non-sementara seperti 400 Permintaan Buruk atau 404 Tidak Ditemukan.
Pengecualian dalam Windows.Web.Http
Pengecualian dimunculkan ketika string Uniform Resource Identifier (URI) yang tidak valid diteruskan ke konstruktor objek Windows.Foundation.Uri.
.NET: Tipe Windows.Foundation.Uri muncul sebagai System.Uri di C# dan VB.
Dalam C# dan Visual Basic, kesalahan ini dapat dihindari dengan menggunakan kelas System.Uri di .NET 4.5 dan salah satu metode System.Uri.TryCreate untuk menguji string yang diterima dari pengguna sebelum URI dibuat.
Di C++, tidak ada metode untuk mencoba dan mengurai string ke URI. Jika aplikasi menerima input dari pengguna untuk Windows.Foundation.Uri, konstruktor harus ditempatkan dalam blok try/catch. Jika pengecualian dilemparkan, aplikasi dapat memberi tahu pengguna dan meminta nama host baru.
Windows. Web.Http tidak memiliki fungsi kenyamanan. Jadi aplikasi yang menggunakan HttpClient dan kelas lain di namespace layanan ini perlu menggunakan nilai HRESULT .
Dalam aplikasi yang menggunakan C++/WinRT, struktur winrt::hresult_error mewakili pengecualian yang dimunculkan selama eksekusi aplikasi. Fungsi winrt::hresult_error::code mengembalikan HRESULT yang ditetapkan ke pengecualian tertentu. Fungsi winrt::hresult_error::message mengembalikan string yang disediakan sistem yang terkait dengan nilai HRESULT . Untuk informasi selengkapnya, lihat Penanganan kesalahan dengan C++/WinRT
Nilai HRESULT yang mungkin tercantum dalam file header Winerror.h . Aplikasi Anda dapat memfilter nilai HRESULT tertentu untuk memodifikasi perilaku aplikasi tergantung pada penyebab pengecualian.
Dalam aplikasi yang menggunakan .NET Framework 4.5 di C#, VB.NET, System.Exception mewakili kesalahan selama eksekusi aplikasi saat pengecualian terjadi. Properti System.Exception.HResult mengembalikan HRESULT yang ditetapkan ke pengecualian tertentu. Properti System.Exception.Message mengembalikan pesan yang menjelaskan pengecualian.
C++/CX telah digantikan oleh C++/WinRT. Tetapi dalam aplikasi yang menggunakan C++/CX, Platform::Exception mewakili kesalahan selama eksekusi aplikasi saat pengecualian terjadi. Properti Platform::Exception::HResult mengembalikan HRESULT yang ditetapkan ke pengecualian tertentu. Properti Platform::Exception::Message mengembalikan string yang disediakan sistem yang terkait dengan nilai HRESULT .
Untuk sebagian besar kesalahan validasi parameter, nilai HRESULT yang dikembalikan adalah E_INVALIDARG. Untuk beberapa panggilan metode ilegal, HRESULT yang dikembalikan adalah E_ILLEGAL_METHOD_CALL.
Topik terkait
Windows developer