使用可能有或可能没有尾随/';s
本文关键字:可能有 | 更新日期: 2023-09-27 18:26:23
我在代码中使用HttpClient已经有一段时间了,一直觉得它对Uris
的使用导致了我的实现中的一些脆弱性。我们的大多数服务端点基本地址都在应用程序中/web.config。因此,它们可以很容易地更改。
我发现,当使用这些端点字符串生成Uri
时,如果它们不以/
结尾,我会得到非常不稳定的行为。当使用非/
终止的BaseAddress
调用GetAsync()
时,发送GET请求的连接URL通常会删除BaseAddress
中最后一个/
之后的字符串,或者会删除GetUri中第一个/
之前的字符串。
例如:
BaseAddress
:http://test/serviceEndpoint
GetUri
:api/customer
当使用该GetUri
调用HttpClient.GetAsync()
时,它将尝试从http://test/api/customer
获取。如果我用/
来限制BaseAddress
,那么一切都如预期的那样工作。
我的问题是BaseAddress
是配置驱动的,在.config文件中添加一条注释"确保用/
结束所有服务URL!"是一个非常脆弱的解决方案。
因此,我养成了在所有HttpClient
构建中使用以下代码的习惯:
var service = settings.GetValue("ServiceBaseUrl");
var serviceUri = !service.EndsWith("/")
? new Uri(service + "/")
: new Uri(service);
_client = new HttpClient
{
BaseAddress = serviceUri
};`
虽然这并不脆弱,但在每个HttpClient
构造函数中都有它会让人感觉重复。HttpClient
或Uri
中有什么东西可以用来避免这个样板代码吗?
HttpClient或Uri中没有任何内容可以解决这个问题,这就是为什么我在Flurl中用几种方式解决了这个问题。Flurl的AppendPathSegment
和AppendPathSegments
方法将确保段之间只有一个"/"分隔符。例如,这些产生了相同的结果:
"http://mysite/".AppendPathSegment("/endpoint")
"http://mysite".AppendPathSegment("endpoint")
静态Url.Combine
方法也有这种行为,充当URL的Path.Combine
。
核心Flurl包中提供了这些和其他有用的URL构建位,但真正有趣的是Flurl.Http,它将流畅的URL构建器与HttpClient和Json.NET之上的轻量级包装器相结合,可以让你从字符串到URL再到Http请求,无需动笔即可反序列化结果,可以说:
var result = await settings.GetValue("ServiceBaseUrl")
.AppendPathSegment("endpoint")
.GetJsonAsync<T>();