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
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 .
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.
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.
A URI parameter identifies a specific resource whereas a Query Parameter is used to sort or filter resources.
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);
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With