tmenier / Flurl

Fluent URL builder and testable HTTP client for .NET
https://flurl.dev
MIT License
4.23k stars 387 forks source link

Hash fragment is getting moved to the end of the Url #724

Closed jovball closed 2 years ago

jovball commented 2 years ago

I am using the Flurl library to build urls but running into one confusing issue. I have a url with a hash fragment such as "https://example.com/#/myFragment". If I use either SetQueryParam or AppendPathSegment, the values will be added after the domain and the hash fragment will be moved to the end. ` var baseUrl = "https://example.com/#/myFragment"; var targetUrl = baseUrl.AppendPathSegment("abc"); //expecting "https://example.com/#/myFragment/abc" but getting "https://example.com/abc#/myFragment/"; Console.WriteLine(targetUrl);

targetUrl = baseUrl.SetQueryParam("x", "123"); //expecting "https://example.com/#/myFragment?x=123" but getting "https://example.com/?x=123#/myFragment/"; Console.WriteLine(targetUrl); ` I can work around this using Url.Combine and more basic string interpolation but it seems like a flaw in the library.

tmenier commented 2 years ago

This is the expected behavior. AppendPathSegment and SetQueryParam refer to the path and query components of the URI respectively, and those always appear to the left of the fragment.

https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax

Flurl has no notion of paths or queries within the fragment because fragments are more of a client-side concern and (as far as I know) there aren't any standards for this. You're probably more likely to find structured fragment building in a client-side library. One possible approach in Flurl is to create a relative Url to represent the fragment and append it when you're done building it:

var fragment = new Url("/myFragment");
fragment.AppendPathSegment(...).SetQueryParam(...)...;
fullUrl.SetFragment(fragment);