为什么 HttpClient 的 BaseAddress 不起作用?
为什么 HttpClient 的 BaseAddress 不起作用?
考虑以下代码,其中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 这里到底发生了什么?
admin 更改状态以发布 2023年5月23日
参考解析由RFC 3986 统一资源标识符(URI):通用语法描述。这正是它的工作原理。为保留基本URI路径,您需要在基本URI结尾添加斜杠,并删除相对URI开头的斜杠。
如果基本URI包含非空路径,则合并程序会丢弃其最后一部分(最后一个“ / ”之后的部分)。相关的部分:
5.2.3. 合并路径
上述伪代码引用了用于将相对路径引用与基本URI路径合并的“合并”例程。完成方式如下:
- 如果基本URI具有已定义的授权组件和空路径,则返回一个字符串,“/”与引用的路径连接;否则
- 返回一个字符串,其中包含引用的路径组件附加到基本URI路径的所有部分,除了最后一段(即,不包括基本URI路径中右侧最靠后的“/”后面的任何字符,或者如果不包含任何“ / ”字符,则不包括整个基本URI路径)。
如果相对URI以斜杠开头,则称为绝对路径相对URI。在这种情况下,合并过程将忽略所有基本URI路径。有关更多信息,请查看5.2.2. 转换引用部分。
原来,在 GetAsync
方法或其他 HttpClient
方法中,对于BaseAddress
和传递的相对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
行为引起的。