Tim*_*lds 255 .net c# dotnet-httpclient
请考虑以下代码,其中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");
}
Run Code Online (Sandbox Code Playgroud)
我希望这可以执行GET请求http://something.com/api/resource/7.但事实并非如此.
经过一番搜索,我发现这个问题和答案: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");
}
Run Code Online (Sandbox Code Playgroud)
它仍然无法正常工作.这是文档:HttpClient.BaseAddress这里发生了什么?
Tim*_*lds 605
事实证明,在BaseAddress传递给GetAsync方法的相对URI 上包含或排除尾随或前导斜杠的四种可能的排列中,或者无论其他方法是什么HttpClient- 只有一种排列有效.您必须在结尾处放置斜杠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");
}
Run Code Online (Sandbox Code Playgroud)
即使我回答了我自己的问题,我想我会在这里提供解决方案,因为这种不友好的行为再次没有记录.我的同事和我一天大部分时间都在努力解决最终由这种奇怪问题引起的问题HttpClient.
Leo*_*lev 48
RFC 3986统一资源标识符(URI):通用语法描述了参考解析.这正是它应该如何运作的.要保留基URI路径,您需要在基URI的末尾添加斜杠,并在相对URI的开头删除斜杠.
如果基URI包含非空路径,则合并过程会丢弃它的最后一部分(最后一个/).相关部分:
5.2.3.合并路径
上面的伪代码指的是用于将相对路径引用与基URI的路径合并的"合并"例程.这完成如下:
如果基URI具有已定义的权限组件和空路径,则返回由引用的路径连接的"/"组成的字符串; 除此以外
返回一个字符串,该字符串包含附加到基URI路径的最后一段之外的所有引用的引用路径组件(即,排除基URI路径中最右侧"/"之后的任何字符,或者排除整个基本URI路径,如果它不包含任何"/"字符).
如果相对URI以斜杠开头,则称为绝对路径相对URI.在这种情况下,合并过程忽略所有基URI路径.有关更多信息,请查看5.2.2.转换参考部分.
Ima*_*idi 19
如果您使用的是 httpClient。SendAsync () 没有用于提供相对 Uris 的字符串重载,例如 Get 或其他动词特定方法的重载。
但是您可以通过将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();
Run Code Online (Sandbox Code Playgroud)
我也遇到了同样的问题BaseAddress。我决定根本不使用,BaseAddress最简单的解决方案是简单的一行添加:
Uri GetUri(string path) => new Uri("http://something.com/api" + path);
Run Code Online (Sandbox Code Playgroud)
那么你的代码将变成:
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"));
}
Run Code Online (Sandbox Code Playgroud)
我还没有研究过使用它的利弊BaseAddress,但对我来说这工作完美。希望这对某人有帮助。
| 归档时间: |
|
| 查看次数: |
72880 次 |
| 最近记录: |