Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access properties of Uri defined with UriKind.Relative

Tags:

c#

uri

My method receives a URI as a string and attempts to parse it into a predictable and consistent format. The incoming URL could be absolute (http://www.test.com/myFolder) or relative (/myFolder). Absolute URIs are easy enough to work with, but I've hit some stumbling blocks working with relative ones. Most notable is the fact that, although the constructor for Uri allows you to designate a relative URI using UriKind.Relative (or UriKind.RelativeOrAbsolute), it doesn't appear to have any properties available when you do this.

Specifically, it throws this exception: System.InvalidOperationException : This operation is not supported for a relative URI.

It makes sense that you wouldn't be able to access, say, the Scheme or Authority properties--although it seems weird that they actually throw invalid operation exceptions instead of just returning blank strings--but even properties like PathAndQuery or Fragment exhibit the same behavior. In fact, pretty much the only properties that don't throw exceptions for relative URIs are the IsX flags and OriginalString, which just shows the string you passed in to the the object in the first place.

Given that that constructor explicitly allows you to declare a relative URI, this all seems like a baffling omission. Is there something I'm missing here? Is there any way to handle relative URIs as their component parts, or do I need to just treat it as a string? Am I completely failing to understand what "relative URI" means in this case?

To replicate:

var uri = new Uri("/myFolder");
string foo = uri.PathAndQuery; // throws exception

Visual Studio Pro 2015, .NET 4.5.2 (if any of that makes a difference)

like image 488
Michael Smith Avatar asked Sep 19 '18 19:09

Michael Smith


1 Answers

It's by design that an exception gets thrown when accessing eg. PathAndQuery for a relative uri, see uri source code.

As a rather quick and dirty workaround to parse some segments, you could construct a temporary absolute uri out of the relative one, using a dummy base uri (scheme and host) which you ignore.

String url = "/myFolder?bar=1#baz";
Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);

if (!uri.IsAbsoluteUri)
{
    Uri baseUri = new Uri("http://foo.com");
    uri = new Uri(baseUri, uri);
}

String pathAndQuery = uri.PathAndQuery; // /myFolder?bar=1
String query = uri.Query; // ?bar=1
String fragment = uri.Fragment; // #baz
like image 51
pfx Avatar answered Sep 28 '22 19:09

pfx