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

时间:2015-12-10 17:11:07

标签: c# uri dotnet-httpclient

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

我发现在使用这些端点字符串生成Uri时,如果它们不以/结尾,我会得到非常不稳定的行为。使用非GetAsync()终止/调用BaseAddress时,发送GET请求的结果连接网址通常会在/中的BaseAddress之后删除字符串{1}},或者它会删除GetUri中第一个/之前的字符串。

例如:

BaseAddresshttp://test/serviceEndpoint

GetUriapi/customer

当使用HttpClient.GetAsync()调用GetUri时,它将尝试从http://test/api/customer获取。如果我使用BaseAddress限制/,则一切都按预期工作。

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

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

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

        _client = new HttpClient
        {
            BaseAddress = serviceUri
        };`

虽然这并不脆弱,但在每个HttpClient构造函数中都有重复性。我可以使用HttpClientUri中的某些内容来避免此样板代码吗?

1 个答案:

答案 0 :(得分:2)

HttpClient或Uri中没有任何内容可以解决这个问题,这就是我在Flurl中以几种方式解决这个问题的原因。 Flurl的AppendPathSegmentAppendPathSegments方法将确保只有一个" /"段之间的分隔符。例如,这些产生相同的结果:

"http://mysite/".AppendPathSegment("/endpoint")
"http://mysite".AppendPathSegment("endpoint")

静态Url.Combine方法也有此行为,作为网址Path.Combine的一种。

核心Flurl包中提供了这些和其他有用的URL构建位,但真正有趣的是Flurl.Http,它将流畅的URL构建器与HttpClient之上的轻量级包装器结合在一起, Json.NET,允许你从字符串到URL到HTTP请求到反序列化的结果,而不用从纸上拿笔,可以这么说:

var result = await settings.GetValue("ServiceBaseUrl")
    .AppendPathSegment("endpoint")
    .GetJsonAsync<T>();