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构造函数中都有重复性.是否有任何东西HttpClient或Uri我可以用来避免这个样板代码?
HttpClient 或 Uri 中没有任何内容可以解决这个问题,这就是为什么我在Flurl中通过多种方式解决了这个问题。Flul 的AppendPathSegment和AppendPathSegments方法将确保段之间只有一个“/”分隔符。例如,这些会产生相同的结果:
"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)