HttpClient在某些情况下修改BaseAddress

Mel*_*per 3 .net c# uri dotnet-httpclient

在基本层面上,我应该能够设置绝对值BaseAddressHttpClient然后使用相对值发送 Http 请求Uri。期望的是相对的Uri将附加到基地址以进行 Http 调用。大多数情况下它都会这样做。这个例子效果很好。

编辑:见底部。从 Uris 的构建方式来看,这似乎是一种奇怪的行为。

var httpClient = new HttpClient() { BaseAddress = new Uri("http://restcountries.eu/rest/", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("v2", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var json = await httpResponseMessage.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud)

提琴手网址:

获取http://restcountries.eu/rest/v2 HTTP/1.1

我有一个本地 API。当我在本地 API 上运行等效项时,调用会截断部分基地址(“Api”)。

var httpClient = new HttpClient() { BaseAddress = new Uri($"http://localhost/JsonPerson/Api", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("GetApiPerson", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var json = await httpResponseMessage.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud)

提琴手网址:

获取 http://localhost/JsonPerson/GetApiPerson HTTP/1.1

为什么要删除“/Api”?

此代码访问本地 API 并且工作正常:

var httpClient = new HttpClient() { BaseAddress = new Uri($"http://localhost/JsonPerson/", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("Api/GetApiPerson", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var json = await httpResponseMessage.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud)

提琴手网址:

获取 http://localhost/JsonPerson/Api/GetApiPerson HTTP/1.1

这是一个奇怪的问题,我不明白为什么会出现这些不一致的情况...对于本地和非本地 uri 是否以不同的方式处理 uri?我在这里缺少什么?

这是.NET Core 3.1

查看此代码,然后查看输出。这就是HttpClient幕后所做的事情。

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var baseAddress = new Uri($"http://restcountries.eu/JsonPerson/Api", UriKind.Absolute);
            var resourceUri = new Uri($"GetApiPerson", UriKind.Relative);
            Console.WriteLine(new Uri(baseAddress, resourceUri));

            baseAddress = new Uri($"http://restcountries.eu/JsonPerson", UriKind.Absolute);
            resourceUri = new Uri($"Api/GetApiPerson", UriKind.Relative);
            Console.WriteLine(new Uri(baseAddress, resourceUri));

            baseAddress = new Uri($"http://restcountries.eu/rest/", UriKind.Absolute);
            resourceUri = new Uri($"v2", UriKind.Relative);
            Console.WriteLine(new Uri(baseAddress, resourceUri));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

http://restcountries.eu/JsonPerson/GetApiPerson

http://restcountries.eu/Api/GetApiPerson

http://restcountries.eu/rest/v2

事实证明,这件事好像跟它有关系……

https://github.com/microsoft/referencesource/blob/f461f1986ca4027720656a0c77bede9963e20b7e/System/net/System/UriExt.cs#L742

Mel*_*per 6

在末尾加上斜线可以BaseAddress解决问题。

然而,这对我来说似乎是一个错误Uri。我确信这会让很多人绊倒。

我创建了一个名为Urls 的库来解决这个问题。URL 是不可变的,您不必使用字符串来构造它们。

RestClient.Net是一个使用这些 url 的 REST/HTTP 客户端库。您可以在此处阅读有关该问题的更多信息。