I noticed I could pass string.Empty to the Url constructor, and that correctly created a relative URL which is exactly what I wanted. Cool.
Then, I proceeded to convert it to a Uri instance using .ToUri and was greeted and an exception (which was to be expected once I saw how it was implemented):
System.UriFormatException: Invalid URI: The format of the URI could not be determined
It looks like Url is just calling the simple Uri constructor on conversions, which will of course fail if the URL is not absolute.
While I understand absolute urls is the more common scenario, this issue needs to be fixed for relative urls.
I can see two potential approaches to fix this:
Uri constructor with the proper UriKind on all conversions.For now, I'm going to create a custom extension method (something like .ToRelativeUri() to avoid this problem, but I wish I didn't need to.
Sorry for the delay. This is interesting. To be honest, I never intended to support relative URLs. But if that's a useful thing and it's already close to working, I might consider closing the gaps.
In my mind it doesn't make much sense to support it anywhere on the HTTP side, so I'd want to catch it and perhaps throw a custom exception whenever you "cross over" to Flurl.Http, such as calling url.GetAsync() etc. (A FlurlRequest always gets created implicitly at that point, so that ctor might be the only place that needs to happen.)
Just curious though - what is your use case for relative URLs?
After looking things over I've decided "officially" supporting relative URLs makes sense, but I'm going to make it a 3.0 enhancement, mainly because I'd like to change the meaning of the IsValid() method, which would be breaking. Here's a to-do list for this one as I see it:
IsValid to return true for valid relative or absolute URLs, and make it a property instead of a methodIsAbsolute propertyToUri so it doesn't throw on valid relative URLs (as originally reported)IsAbsolute check to FlurlClient and FlurlRequest constructorsI'm actively gathering feedback to help prioritize issues for 3.0. If this one is important to you, please vote for it here!
I'm scaling back my ambitions on this one a bit. It's hard to decide what the exact behavior of IsValid should be in the case of a relative URL. I find the behavior of Uri.IsWellFormed a little awkward/confusing in this case, so I'm thinking I might just err on the side of leaving it alone. i.e. IsValid() returns true if it's a valid _absolute_ URL, otherwise false. (I'll better document it too.)
Aside that and the specific ToUri bug originally reported, I don't believe there's any gaps in functionality related to using Flurl to build relative URLs. So I'll treat this issue just as a bug fix. If anyone has other thoughts, please chime in.
Apologies for taking so long to report back on this.
Just curious though - what is your use case for relative URLs?
I needed this one to build a relative URL inside a class relying on an injected HttpClient class with a populated BaseAddress. In this scenario, the class only handles the relative part of the URL, while the aggregation root is responsible for constructing it with the correct base.
This same requirement appeared again in a different project now (that's when I noticed the latest version still didn't have support for relative URLs and reminded me of this issue).
I have julealgon's same use case.
Most helpful comment
After looking things over I've decided "officially" supporting relative URLs makes sense, but I'm going to make it a 3.0 enhancement, mainly because I'd like to change the meaning of the
IsValid()method, which would be breaking. Here's a to-do list for this one as I see it:IsValidto return true for valid relative or absolute URLs, and make it a property instead of a methodIsAbsolutepropertyToUriso it doesn't throw on valid relative URLs (as originally reported)IsAbsolutecheck toFlurlClientandFlurlRequestconstructors