Using Uri strings, which may or may not have trailing /

I used HttpClient in the code for a while and always believed that its use of Uris led to some fragility in my implementation. Most service endpoint base addresses are in the app./web.config file. As a result, they can be easily changed.

I found that when using these endpoint lines to create a Uri , if they don't end with / , I get really elusive behavior. When calling GetAsync() with the / -terminated BaseAddress BaseAddress , a non-concatenated URL that is sent by the GET request often leaves a line after the final / in BaseAddress , or it discards the line preceding the first / in GetUri.

For instance:

BaseAddress : http://test/serviceEndpoint

GetUri : api/customer

When HttpClient.GetAsync() is called with this GetUri , it will try to get from http://test/api/customer . If I close BaseAddress with / , everything works as expected.

My problem is that BaseAddress is configuration-controlled and puts a comment in the .config file saying "Make sure you complete all the service urls with / !". this is a really fragile decision.

So, I'm used to using the following code in my entire HttpClient construct:

  var service = settings.GetValue("ServiceBaseUrl"); var serviceUri = !service.EndsWith("/") ? new Uri(service + "/") : new Uri(service); _client = new HttpClient { BaseAddress = serviceUri };` 

While it is not fragile, it feels repetitive to have it in every HttpClient constructor. Is there anything in HttpClient or Uri that I can use to avoid this pattern?

+5
source share
1 answer

There is nothing in HttpClient or Uri to solve this problem, so I addressed it in several ways in Flurl . The Flurl AppendPathSegment and AppendPathSegments provide one and only one "/" separator between segments. For example, they give the same results:

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

The static Url.Combine method also has this behavior, acting like a Path.Combine view for URLs.

These and other useful URL building bits are available in the Flurl core package, but the real fun is in Flurl.Http , which combines a smooth URL builder with a lightweight wrapper on top of HttpClient and Json.NET, which allows you to go from line to URL The address of the HTTP request for deserialization is the result without lifting the pen from the paper, so to speak:

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

Source: https://habr.com/ru/post/1237865/


All Articles