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");
}
我希望它对
GET
执行http://something.com/api/resource/7
请求。但是没有。经过一番搜索,我找到了这个问题并回答:带有BaseAddress的HttpClient。建议将
/
放在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这是怎么回事?
#1 楼
事实证明,在包括或排除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
的这种怪异而导致的问题。评论
谢谢。这解决了我在两天的大部分时间里一直在苦苦挣扎的问题,在切换到Azure,回到IIS和再回到IIS Express之间,这最不礼貌地忽略了放错位置或多余的正斜杠。一旦在我的RestClient的基类中设置了它,它几乎是不可见的,根本没有引起任何注意,并且我在断点等处从未看到完整的URL。
– ProfK
16/12/13在14:32
我可以确认这种怪异(和此修复程序)在.NET Core中仍然有用。感谢您减少我的头发提摩太。
–内特·巴贝蒂尼(Nate Barbettini)
17 Mar 29 '17 at 19:32
这是因为在生成请求时不加任何斜杠,它会丢弃最后一部分。因此,它访问了something.com/resource/7。如果您将基址设置为something / com(是否带斜杠也没关系),则将斜杠放在api / resource / 7的开头也没关系。没有尾部斜杠时,基地址的最后部分被视为文件,并在建立请求时删除。
–彼得·霹雳
17-6-27 at 7:52
这不是直接解决原始问题,而是相关的。对于每个Mircosoft,应将HttpClient()的实例分配给静态变量并重用(docs.microsoft.com/zh-cn/aspnet/web-api/overview/advanced/…-每个请求创建一个新的HttpClient实例都会耗尽可用的套接字)。因此,您应该考虑删除Using()。
– sanmcp
17年12月11日在3:24
只是一个可怕的实现。他们为什么不解决这个问题?
–timmkrause
18-10-30在16:14
#2 楼
参考解析由RFC 3986统一资源标识符(URI):通用语法描述。这正是它应该如何工作的。要保留基本URI路径,您需要在基本URI的末尾添加斜杠,并在相对URI的开始处删除斜杠。如果基本URI包含非空路径,则合并过程将丢弃它的最后一部分(在最后一个
/
之后)。相关部分:5.2.3。合并路径
上面的伪代码引用了一个“合并”例程,用于将相对路径引用与基本URI的路径合并。这是通过以下步骤完成的:
如果基本URI具有已定义的权限组件和空的
路径,则返回由“ /”串联而成的字符串带有
引用的路径;否则
返回一个字符串,该字符串包含引用的路径部分组成的字符串
,附加到基本URI路径的最后一段以外的所有部分(即,
不包括最右端“ /”后面的任何字符)基本URI
路径,如果不包含任何字符,则排除整个基本URI路径)。
如果是相对URI以斜杠开头,它称为绝对路径相对URI。在这种情况下,合并过程将忽略所有基本URI路径。有关更多信息,请检查5.2.2。变换参考部分。
评论
很好,但是客户端库(例如HttpClient)应该使我们免受诸如此类的深奥实现细节的困扰。
–杰米·艾德(Jamie Ide)
20年1月16日在15:11
答案涵盖原因为何如此有效,并带有相关的链接和引号非常好。即使这对直接解决问题没有帮助,也很有帮助。
–Rast
20年6月21日在16:18
#3 楼
即使提出了建议,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
});
评论
可能与具有BaseAddress的HttpClient重复
@ГеоргийЛанец已经提出反向重复。我之所以写这个问题,是因为其他问题不是以同样的问题的人很容易发现的方式写的,而我之所以在这里写下答案,是因为那里的答案遗漏了一个重要的观点。
但是稍后会问这个问题
@ГеоргийЛанец这不是它的工作原理。通常,最“规范”的问题是使指向该问题的重复项的问题。另一个问题是关于用户遇到的一个问题,而不是像常见问题解答那样阅读。
@ГеоргийЛанец同时请注意,我引用了该问题中的另一个问题,并解释了为什么另一个问题和答案不足以解决问题。