[英]Why is HttpClient BaseAddress not working?
考慮以下代碼,其中BaseAddress
定義了部分 URI 路徑。
using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("http://something.com/api");
var response = await client.GetAsync("/resource/7");
}
我希望這對http://something.com/api/resource/7
執行GET
請求。 但事實並非如此。
經過一番搜索,我找到了這個問題和答案: HttpClient with BaseAddress 。 建議將/
放在BaseAddress
的末尾。
using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("http://something.com/api/");
var response = await client.GetAsync("/resource/7");
}
它仍然不起作用。 這是文檔: HttpClient.BaseAddress這里發生了什么?
事實證明,在BaseAddress
上包含或排除尾隨或前導正斜杠的四種可能排列以及傳遞給GetAsync
方法(或HttpClient
任何其他方法)的相對 URI 中,只有一種排列有效。 您必須在BaseAddress
的末尾放置斜杠,並且不得在相對 URI 的開頭放置斜杠,如下例所示。
using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("http://something.com/api/");
var response = await client.GetAsync("resource/7");
}
盡管我回答了我自己的問題,但我想我會在這里提供解決方案,因為這種不友好的行為是沒有記錄的。 我和我的同事花了一天的大部分時間試圖解決最終由HttpClient
的這種奇怪之處引起的問題。
RFC 3986 Uniform Resource Identifier (URI): Generic Syntax描述了參考解析。 這正是它應該如何工作的。 要保留基本 URI 路徑,您需要在基本 URI 的末尾添加斜杠並在相對 URI 的開頭刪除斜杠。
如果基本 URI 包含非空路徑,合並過程將丟棄它的最后一部分(在最后/
)。 相關部分:
5.2.3. 合並路徑
上面的偽代碼指的是用於將相對路徑引用與基本 URI 的路徑合並的“合並”例程。 這是按如下方式完成的:
如果基本 URI 具有定義的權限組件和空路徑,則返回由“/”與引用路徑連接組成的字符串; 除此以外
返回一個字符串,該字符串包含附加到除基本 URI 路徑的最后一部分之外的所有部分的引用路徑組件(即,排除基本 URI 路徑中最右邊的“/”之后的任何字符,或者排除整個基本 URI 路徑,如果它不包含任何“/”字符)。
如果相對 URI 以斜杠開頭,則稱為絕對路徑相對 URI。 在這種情況下,合並過程會忽略所有基本 URI 路徑。 有關更多信息,請查看5.2.2。 轉換參考部分。
我也遇到了同樣的問題BaseAddress
。 我決定根本不使用BaseAddress
,最簡單的解決方案是簡單的單行添加:
Uri GetUri(string path) => new Uri("http://something.com/api" + path);
那么你的代碼將變成:
Uri GetUri(string path) => new Uri("http://something.com/api" + path);
using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
// Remove BaseAddress completely
// client.BaseAddress = new Uri("http://something.com/api");
var response = await client.GetAsync(GetUri("/resource/7"));
}
我還沒有調查過使用BaseAddress
利弊,但對我來說這完美無缺。 希望這可以幫助某人。
如果您使用的是 httpClient。 SendAsync () 沒有像 Get、Post 和其他動詞特定方法中的重載那樣的字符串重載。
但是您可以通過將UriKind.Relative作為第二個參數來創建相對 Uri
var httpRequestMessage = new HttpRequestMessage
{
Method = httpMethod,
RequestUri = new Uri(relativeRequestUri, UriKind.Relative),
Content = content
};
using var httpClient = HttpClientFactory.CreateClient("XClient");
var response = await httpClient.SendAsync(httpRequestMessage);
var responseText = await response.Content.ReadAsStringAsync();
或者 - 根本不使用BaseAddress
。 將整個URL放在GetAsync
()中
遇到了 HTTPClient 的問題,即使有建議仍然無法對其進行身份驗證。 原來我的相對路徑中需要一個尾隨的“/”。
IE
var result = await _client.GetStringAsync(_awxUrl + "api/v2/inventories/?name=" + inventoryName);
var result = await _client.PostAsJsonAsync(_awxUrl + "api/v2/job_templates/" + templateId+"/launch/" , new {
inventory = inventoryId
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.