Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't System.Uri recognize query parameter for local file path?

I need to add some additional query information to file path as query parameter to parse path later during files processing. I though that System.Uri class can help me with this, but it looks like it doesn't give me what I expected for local file paths.

var fileUri = new Uri("file:///c://a.txt?select=10")
// fileUri.AbsoluteUri = "file:///c://a.txt%3Fselect=10"
// fileUri.Query = ""

var httpUri = new Uri("http://someAddress/a.txt?select=10")
// httpUri.AbsoluteUri = "http://someaddress/a.txt?select=10"
// httpUri.Query = "?select=10"

In the case of "ftp://someAddress/a.txt?select=10" - query string is also empty

I understand that System.Uri probably resolves "a.txt?select=10" to correct file name "a.txt%3Fselect=10", but WHY - how to escape this?

Thanks in advance

like image 665
Vitaliy Avatar asked Jan 06 '12 12:01

Vitaliy


People also ask

Can a URI be a file path?

The single slash between host and path denotes the start of the local-path part of the URI and must be present. A valid file URI must therefore begin with either file:/path (no hostname), file:///path (empty hostname), or file://hostname/path .

Are query parameters part of URI?

URI parameter (Path Param) is basically used to identify a specific resource or resources whereas Query Parameter is used to sort/filter those resources. Let's consider an example where you want identify the employee on the basis of employeeID, and in that case, you will be using the URI param.

Are query parameters part of the path?

Conclusion. While query parameters describe how to look, path parameters show your program where to look. Path parameters are part of the endpoint URI and are required to have a value. Think of path parameters as the file system in your endpoint URL, guiding the request to the answer it seeks.

What is URI parameter and query parameter?

A URI parameter identifies a specific resource whereas a Query Parameter is used to sort or filter resources.


1 Answers

This is a bug which Microsoft won't fix : Bug 594562 As you can see they propose reflection as an workaround:

...
Console.WriteLine("Before");
Uri fileUri = new Uri("file://host/path/file?query#fragment");
Console.WriteLine("AbsoluteUri: " + fileUri.AbsoluteUri);
Console.WriteLine("ToString: " + fileUri.ToString());
Console.WriteLine("LocalPath: " + fileUri.LocalPath);
Console.WriteLine("Query: " + fileUri.Query);
Console.WriteLine("Fragment: " + fileUri.Fragment);

Type uriParserType = typeof(UriParser);
FieldInfo fileParserInfo = uriParserType.GetField("FileUri", BindingFlags.Static | BindingFlags.NonPublic);
UriParser fileParser = (UriParser)fileParserInfo.GetValue(null);
FieldInfo fileFlagsInfo = uriParserType.GetField("m_Flags", BindingFlags.NonPublic | BindingFlags.Instance);
int fileFlags = (int)fileFlagsInfo.GetValue(fileParser);
int mayHaveQuery = 0x20;
fileFlags |= mayHaveQuery;
fileFlagsInfo.SetValue(fileParser, fileFlags);

Console.WriteLine();
Console.WriteLine("After");
fileUri = new Uri("file://host/path/file?query#fragment");
Console.WriteLine("AbsoluteUri: " + fileUri.AbsoluteUri);
Console.WriteLine("ToString: " + fileUri.ToString());
Console.WriteLine("LocalPath: " + fileUri.LocalPath);
Console.WriteLine("Query: " + fileUri.Query);
Console.WriteLine("Fragment: " + fileUri.Fragment);  
...  
like image 63
VMykyt Avatar answered Sep 21 '22 06:09

VMykyt