使用Uri字符串,可能有也可能没有尾随/

Gar*_*ely 5 c# uri dotnet-httpclient

我已经在代码中使用HttpClient一段时间了,并且一直觉得它的使用Uris导致了我的实现中的一些脆弱性.我们的大多数服务端点基地址都在app./web.config中.结果,它们可以很容易地改变.

我发现当使用这些端点字符串生成a时Uri,如果它们不以a结尾/,我会得到非常不稳定的行为.当调用GetAsync()与非/封端的BaseAddress,即常发送的GET请求所得级联URL后最终下降任一字符串/中的BaseAddress,或者它会下降字符串前述第一/在GetUri.

例如:

BaseAddress: http://test/serviceEndpoint

GetUri: api/customer

HttpClient.GetAsync()GetUri它调用时,它将尝试从中获取http://test/api/customer.如果我BaseAddress用a 封顶/,一切都按预期工作.

我的问题BaseAddress配置驱动,并在.config文件中添加注释,说"请确保使用/!结束所有服务URL ".是一个非常脆弱的解决方案.

所以我养成了在我的所有HttpClient构造中使用以下代码的习惯:

        var service = settings.GetValue("ServiceBaseUrl");
        var serviceUri = !service.EndsWith("/")
            ? new Uri(service + "/")
            : new Uri(service);

        _client = new HttpClient
        {
            BaseAddress = serviceUri
        };`
Run Code Online (Sandbox Code Playgroud)

虽然这不易碎,但在每个HttpClient构造函数中都有重复性.是否有任何东西HttpClientUri我可以用来避免这个样板代码?

Tod*_*ier 3

HttpClient 或 Uri 中没有任何内容可以解决这个问题,这就是为什么我在Flurl中通过多种方式解决了这个问题。Flul 的AppendPathSegmentAppendPathSegments方法将确保段之间只有一个“/”分隔符。例如,这些会产生相同的结果:

"http://mysite/".AppendPathSegment("/endpoint")
"http://mysite".AppendPathSegment("endpoint")
Run Code Online (Sandbox Code Playgroud)

静态Url.Combine方法也有这种行为,就像Path.CombineURL 的 a 一样。

这些和其他有用的 URL 构建位在核心Flurl包中可用,但真正的乐趣在于Flurl.Http,它将流畅的 URL 构建器与 HttpClient 和 Json.NET 之上的轻量级包装器结合在一起,让您可以从字符串开始到 URL 到 HTTP 请求到反序列化结果,无需离纸,可以这么说:

var result = await settings.GetValue("ServiceBaseUrl")
    .AppendPathSegment("endpoint")
    .GetJsonAsync<T>();
Run Code Online (Sandbox Code Playgroud)