HttpClient 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供類別,用於從 URI 所識別的資源傳送 HTTP 要求和接收 HTTP 回應。
public ref class HttpClient : System::Net::Http::HttpMessageInvoker
public class HttpClient : System.Net.Http.HttpMessageInvoker
type HttpClient = class
inherit HttpMessageInvoker
Public Class HttpClient
Inherits HttpMessageInvoker
- 繼承
範例
// HttpClient is intended to be instantiated once per application, rather than per-use. See Remarks.
static readonly HttpClient client = new HttpClient();
static async Task Main()
{
// Call asynchronous network methods in a try/catch block to handle exceptions.
try
{
using HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
// Above three lines can be replaced with new helper method below
// string responseBody = await client.GetStringAsync(uri);
Console.WriteLine(responseBody);
}
catch (HttpRequestException e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} ", e.Message);
}
}
open System.Net.Http
// HttpClient is intended to be instantiated once per application, rather than per-use. See Remarks.
let client = new HttpClient()
let main =
task {
// Call asynchronous network methods in a try/catch block to handle exceptions.
try
use! response = client.GetAsync "http://www.contoso.com/"
response.EnsureSuccessStatusCode() |> ignore
let! responseBody = response.Content.ReadAsStringAsync()
// Above three lines can be replaced with new helper method below
// let! responseBody = client.GetStringAsync uri
printfn $"{responseBody}"
with
| :? HttpRequestException as e ->
printfn "\nException Caught!"
printfn $"Message :{e.Message} "
}
main.Wait()
' HttpClient is intended to be instantiated once per application, rather than per-use. See Remarks.
Shared ReadOnly client As HttpClient = New HttpClient()
Private Shared Async Function Main() As Task
' Call asynchronous network methods in a try/catch block to handle exceptions.
Try
Using response As HttpResponseMessage = Await client.GetAsync("http://www.contoso.com/")
response.EnsureSuccessStatusCode()
Dim responseBody As String = Await response.Content.ReadAsStringAsync()
' Above three lines can be replaced with new helper method below
' Dim responseBody As String = Await client.GetStringAsync(uri)
Console.WriteLine(responseBody)
End Using
Catch e As HttpRequestException
Console.WriteLine(Environment.NewLine & "Exception Caught!")
Console.WriteLine("Message :{0} ", e.Message)
End Try
End Function
上述程式碼範例會使用 async Task Main()
進入點。 該功能需要 C# 7.1 或更新版本。
備註
HttpClient類別執行個體是做為工作階段使用以傳送 HTTP 要求。 HttpClient執行個體是套用至該執行個體所執行之所有要求的設定集合。 此外,每個 HttpClient執行個體都使用自己的連接集區,這樣可將其要求與由其他 HttpClient 執行個體執行的要求隔離。
實例
HttpClient 是要在應用程式生命週期中具現化一次並重複使用。 在 .NET Core 和 .NET 5+ 中,HttpClient 會集區處理常式實例內的連線,並在多個要求之間重複使用連線。 如果您針對每個要求具現化 HttpClient 類別,大量負載下可用的通訊端數目將會耗盡。 此耗盡將會導致 SocketException 錯誤。
您可以藉由傳入「處理常式」來設定其他選項,例如 HttpClientHandler (或 SocketsHttpHandler .NET Core 2.1 或更新版本中的) ,作為建構函式的一部分。 一旦提交要求,就無法變更處理常式上的連接屬性,因此如果您需要變更連接屬性,建立新的 HttpClient 實例的其中一個原因。 如果不同的要求需要不同的設定,這也可能會導致應用程式有多個 HttpClient 實例,其中每個實例都已適當地設定,然後在相關的用戶端上發出要求。
HttpClient 只會在建立連線時解析 DNS 專案。 它不會追蹤 DNS 伺服器所指定 (TTL) 持續時間的任何存留時間。 如果 DNS 專案會定期變更,這可能會在某些容器案例中發生,用戶端將不會遵守這些更新。 若要解決此問題,您可以藉由設定 SocketsHttpHandler.PooledConnectionLifetime 屬性來限制連線的存留期,以便在取代連線時需要 DNS 查閱。
public class GoodController : ApiController
{
private static readonly HttpClient httpClient;
static GoodController()
{
var socketsHandler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(2)
};
httpClient = new HttpClient(socketsHandler);
}
}
除了只建立一個 HttpClient 實例,您也可以使用 IHttpClientFactory 來管理 HttpClient 實例。 如需詳細資訊,請參閱 使用 HttpClient 的指導方針。
衍生
HttpClient也會作為更特定 HTTP 用戶端的基類。 例如,FacebookHttpClient 會提供 Facebook Web 服務特定的其他方法,例如方法 GetFriends
() 。 衍生類別不應覆寫 類別上的虛擬方法。 請改用接受 HttpMessageHandler 的建構函式多載來設定任何預先要求或後續要求處理。
傳輸
HttpClient是高階 API,會包裝其執行所在每個平臺上可用的較低層級功能。
在每個平臺上, HttpClient 嘗試使用最佳的可用傳輸:
主機/執行時間 | 後端 |
---|---|
Windows/.NET Framework | HttpWebRequest |
Windows/Mono | HttpWebRequest |
Windows/UWP | 支援 Windows 原生 WinHttpHandler (HTTP 2.0) |
Windows/.NET Core 1.0-2.0 | 支援 Windows 原生 WinHttpHandler (HTTP 2.0) |
Android/Xamarin | 在建置階段選取。 HttpWebRequest可以使用 或 設定為使用 Android 的原生HttpURLConnection |
iOS、tvOS、watchOS/Xamarin | 在建置階段選取。 HttpWebRequest可以使用 或 設定為使用 Apple NSUrlSession 的 (HTTP 2.0 功能) |
macOS/Xamarin | 在建置階段選取。 HttpWebRequest可以使用 或 設定為使用 Apple NSUrlSession 的 (HTTP 2.0 功能) |
macOS/Mono | HttpWebRequest |
macOS/.NET Core 1.0-2.0 | libcurl 型 HTTP 傳輸 (支援 HTTP 2.0) |
Linux/Mono | HttpWebRequest |
Linux/.NET Core 1.0-2.0 | libcurl 型 HTTP 傳輸 (支援 HTTP 2.0) |
.NET Core 2.1 和更新版本 | System.Net.Http.SocketsHttpHandler |
使用者也可以藉由叫 HttpClient 用採用 HttpMessageHandler 的建構函式,為 設定特定的傳輸 HttpClient 。
&.NET Framework Mono
根據預設,.NET Framework 和 Mono 會 HttpWebRequest 用來將要求傳送至伺服器。 您可以使用 參數,在其中一個建構函式多載 HttpMessageHandler 中指定不同的處理常式,藉此修改此行為。 如果您需要驗證或快取等功能,您可以使用 WebRequestHandler 來設定設定,並將 實例傳遞至建構函式。 傳回的處理常式可以傳遞至具有 參數的 HttpMessageHandler 建構函式多載。
.NET Core
從 .NET Core 2.1 開始, System.Net.Http.SocketsHttpHandler 類別會提供 HttpClientHandler 較高層級 HTTP 網路類別所使用的實作,例如 HttpClient 。 使用 SocketsHttpHandler 提供許多優點:
- 與之前的實作相比,能提供顯著的效能提升。
- 消除平臺相依性,可簡化部署和服務。 例如,
libcurl
不再相依于 macOS 的 .NET Core 和適用于 Linux 的 .NET Core。 - 所有 .NET 平臺的行為一致。
如果不需要這項變更,您可以在 Windows 上繼續使用 WinHttpHandler ,方法是參考其 NuGet 套件 ,並手動將它傳遞至 HttpClient 的建構函 式。
使用執行時間組態選項設定行為
某些層面 HttpClient 的行為可透過 執行時間組態選項來自訂。 不過,這些參數的行為會因 .NET 版本而異。 例如,在 .NET Core 2.1 - 3.1 中,您可以設定是否 SocketsHttpHandler 預設使用 ,但從 .NET 5.0 開始,該選項已不再提供使用。
連線共用
HttpClient 會盡可能集區 HTTP 連線,並將它們用於多個要求。 這可以有顯著的效能優勢,特別是 HTTPS 要求,因為連線交握只會完成一次。
連接集區屬性可以在 建構期間設定 HttpClientHandler 或 SocketsHttpHandler 傳入,包括 MaxConnectionsPerServer 、 PooledConnectionIdleTimeout 和 PooledConnectionLifetime 。
處置 HttpClient 實例會關閉開啟的連接,並取消任何擱置的要求。
注意
如果您同時將 HTTP/1.1 要求傳送至相同的伺服器,則可以建立新的連線。 即使您重複使用 HttpClient
實例,如果要求速率很高,或有任何防火牆限制,可能會因為預設 TCP 清除計時器而耗盡可用的通訊端。 若要限制並行連線的數目,您可以設定 MaxConnectionsPerServer
屬性。 根據預設,並行 HTTP/1.1 連線的數目無限制。
緩衝處理和要求存留期
根據預設,HttpClient 方法會 (,但 GetStreamAsync) 緩衝來自伺服器的回應,先將所有回應本文讀取到記憶體中,再傳回非同步結果。 這些要求會繼續執行,直到發生下列其中一項:
- 成功 Task<TResult> 並傳回結果。
- 已 Timeout 到達 ,在此情況下 Task<TResult> ,將會取消 。
- 會 CancellationToken 引發可傳遞至某些方法多載的 。
- 呼叫 CancelPendingRequests()。
- HttpClient 已處置。
您可以使用某些方法多載上可用的 參數,根據 HttpCompletionOption 每個要求變更緩衝行為。 這個引數可用來指定 讀取回應標頭之後,或讀取和緩衝回應內容之後,是否 Task<TResult> 應該視為完成。
如果您的應用程式使用 HttpClient 命名空間和相關 System.Net.Http 類別想要下載大量資料, (50 MB 以上的) ,則應用程式應該串流處理這些下載,而不會使用預設緩衝。 如果您使用預設緩衝,則用戶端記憶體使用量會非常大,可能會導致大幅降低效能。
執行緒安全
下列方法是安全線程:
- CancelPendingRequests
- DeleteAsync
- GetAsync
- GetByteArrayAsync
- GetStreamAsync
- GetStringAsync
- PostAsync
- PutAsync
- SendAsync
Proxy
根據預設,HttpClient 會根據平臺,從環境變數或使用者/系統設定讀取 Proxy 組態。 您可以依照優先順序將 或 IWebProxy 傳遞 WebProxy 至 來變更此行為:
- Proxy在 HttpClient 建構期間傳入的 HttpClientHandler 屬性
- DefaultProxy靜態屬性 (會影響所有實例)
您可以使用 停用 Proxy UseProxy 。 Windows 使用者的預設設定是使用網路探索來嘗試和偵測 Proxy,這可能會變慢。 對於已知不需要 Proxy 的高輸送量應用程式,您應該停用 Proxy。
只有在使用 HttpClient 提出第一個要求之前,才應該變更) 之類的 Credentials Proxy (設定。 第一次使用 HttpClient 之後所做的變更可能不會反映在後續要求中。
逾時
您可以使用 Timeout 來設定來自 HttpClient 實例之所有 HTTP 要求的預設逾時。 逾時僅適用于導致起始要求/回應的 xxxAsync 方法。 如果達到逾時, Task<TResult> 則會取消該要求的 。
如果您在建構 HttpClient 物件時傳入 SocketsHttpHandler 實例,可以設定一些額外的逾時:
屬性 | 說明 |
---|---|
ConnectTimeout | 指定要求需要建立新 TCP 連線時所使用的逾時。 如果發生逾時,則會取消要求 Task<TResult> 。 |
PooledConnectionLifetime | 指定要用於連接集區中每個連線的逾時。 如果連線閒置,則會立即關閉連線;否則,連線會在目前要求結束時關閉。 |
PooledConnectionIdleTimeout | 如果連線集區中的連線長時間閒置,則會關閉連線。 |
Expect100ContinueTimeout | 如果要求有「預期:100-continue」標頭,它會延遲傳送內容,直到逾時或收到「100-continue」回應為止。 |
HttpClient 只會在建立連線時解析 DNS 專案。 它不會追蹤任何時間 (DNS 伺服器所指定的 TTL) 持續時間。 如果 DNS 專案會定期變更,這可能會在某些容器案例中發生,您可以使用 PooledConnectionLifetime 來限制連線的存留期,以便在取代連線時需要 DNS 查閱。
建構函式
HttpClient() |
使用當處置此執行個體時會處置的 HttpClientHandler 來初始化 HttpClient 類別的新執行個體。 |
HttpClient(HttpMessageHandler) |
使用指定的處理常式初始化 HttpClient 類別的新執行個體。 當處置此執行個體時會處置該處理常式。 |
HttpClient(HttpMessageHandler, Boolean) |
使用提供的處理常式初始化 HttpClient 類別的新執行個體,並指定當處置此執行個體時是否應該處置該處理常式。 |
屬性
BaseAddress |
取得或設定傳送要求時所使用之網際網路資源的統一資源識別元 (URI) 基底位址。 |
DefaultProxy |
取得或設定全域 HTTP Proxy。 |
DefaultRequestHeaders |
取得應該在每個要求中傳送的標頭。 |
DefaultRequestVersion |
取得或設定用於這個 HttpClient 執行個體所提出後續要求的預設 HTTP 版本。 |
DefaultVersionPolicy |
取得或設定透過便利方法以隱含方式所建立要求的預設版本原則,例如 GetAsync(String) 和 PostAsync(String, HttpContent)。 |
MaxResponseContentBufferSize |
取得或設定讀取回應內容時要緩衝處理的位元組數目上限。 |
Timeout |
取得或設定要求逾時前等候的時間長度。 |