Home Dashboard Directory Help

Uri class does not parse filesystem URL with query string by CalebD


 as Won't Fix Help for as Won't Fix

Sign in
to vote
Type: Bug
ID: 594562
Opened: 9/3/2010 1:29:25 PM
Access Restriction: Public
User(s) can reproduce this bug


The Uri class does not correctly recognize query strings on filesystem URLs.

When passing this Uri into a WPF WebBrowser control, an ArgumentException is thrown with the message "Invalid character in path."

See this post for more info: http://social.msdn.microsoft.com/Forums/en-US/ncl/thread/c3ba1672-ea05-4728-a4c1-01c84aa79bdb/#1baa1859-b67c-4dec-832b-af3e0c63d594

This makes it nearly impossible to navigate a WPF webbrowser to a local file and specify a query string, which affects something like a local html-based help system where the desired topic to navigate to is specified through the query string.

There is a workaround, which is to write an html page with a single frame to host the webpage and also insert some javascript to do the page navigation, but it may have other drawbacks.
Sign in to post a comment.
Posted by CalebD on 1/25/2011 at 7:52 PM
I understand, but I still need a workaround.

Perhaps there could be a flag that could be set in an instance of the Uri class that would turn on the bug fix? Or maybe a inherited class that could be used as a Uri?

I suppose it could break something else, but the Uri class is incorrectly parsing the AbsoluteUri string and treating a question mark as a valid filename character, which is not a valid character for the windows filesystem nor for online URLs...
Posted by Microsoft on 1/25/2011 at 6:40 PM
Unfortunately, we cannot fix this bug due to app-compat issues. As you might guess, the URI class is used in many places through a very substantial number of products, including both off-the-shelf applications and internal busines applications. Changes like this have a very real potential for breaking a large number of existing applications.

Posted by CalebD on 1/25/2011 at 2:12 PM
Why has the status been changed to Won't Fix? This is an issue that does not have a reasonable workaround. Could MS provide a workaround?

The workaround mentioned in the description has serious drawbacks, such that I've had to temporarily use a WindowsFormsHost + WebBrowser until (I had hoped) this issue would be fixed.

The WindowsFormsHost workaround has significant drawbacks as well (painting/skinning/dpi bug), but is, at least, not broken.
Posted by Microsoft on 10/20/2010 at 10:04 AM
Thank you for the feedback. We are aware of the issue and plan to address it in a future release.
Posted by CalebD on 9/21/2010 at 9:01 AM
I've tried using the frameset workaround, and various other ways to work around this issue, but to no avail.

Please fix this in .NET 4.0 SP1.
Posted by Microsoft on 9/5/2010 at 9:18 PM
Thank you for reporting the issue.
We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution.These specialized experts will follow-up with your issue.
Posted by Microsoft on 9/3/2010 at 5:04 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by Tratcher on 1/26/2011 at 1:17 PM
You can change the behavior for all new file Uris in your application using reflection:

            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);

            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);