How to create Uri without fragmentation (convert # to %23)

Tim Reinagel

I am trying to do advanced searches by using the query string but when I include # it doesn't get converted to %23 when creating a uri.

var webAddress = "www.worldwideweb.com/abc#d#e";
var uri = new Uri(webAddress).AbsoluteUri;

When I do that, an exception is thrown. When I only include a # symbol it fragments it instead. Like in this example

var webAddress = "https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#] OR [java]"
var uri = new Uri(webAddress).AbsoluteUri;

Uri now equals

https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#]%20OR%20[java]

How do I make

https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#] OR [f#]

into

https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c%23]%20OR%20[f%23]

I'm using .Net Framework 4.6.2

rene

My approach is to use the an UriBuilder and a Dictionary for each Query parameter. You can then UrlEncode the value from each parameter so you get a valid Url.

This is what your code would look like:

var ub = new UriBuilder("https", "api.stackexchange.com");
ub.Path = "/2.2/search/advanced";
// query string parameters
var query = new Dictionary<string,string> ();
query.Add("site", "stackoverflow");
query.Add("q", "[c#] OR [f#]");
query.Add("filter", "!.UE46gEJXV)W0GSb");
query.Add("page","1");
query.Add("pagesize","2");

// iterate over each dictionary item and UrlEncode the value
ub.Query = String.Join("&",
    query.Select(kv => kv.Key + "=" + WebUtility.UrlEncode(kv.Value)));

var wc = new MyWebClient();
wc.DownloadString(ub.Uri.AbsoluteUri).Dump("result");

This will result in this Url in ub.Uri.AbsoluteUri:

https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=%5Bc%23%5D+OR+%5Bf%23%5D&filter=!.UE46gEJXV)W0GSb&page=1&pagesize=2

As the StackAPI returns the content zipped, use AutomaticDecompression on an subclassed WebClient (as shown here by feroze):

class MyWebClient:WebClient
{
   protected override WebRequest GetWebRequest(Uri uri) 
   {   
       var wr = base.GetWebRequest(uri) as HttpWebRequest;
       wr.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
       return wr;
   }
}

which, when combined with the other code, generates output for me:

{
    "items" : [{
            "tags" : ["c#", "asp.net-mvc", "iis", "web-config"],
            "last_activity_date" : 1503056272,
            "question_id" : 45712096,
            "link" : "https://stackoverflow.com/questions/45712096/can-not-read-web-config-file",
            "title" : "Can not read web.config file"
        }, {
            "tags" : ["c#", "xaml", "uwp", "narrator"],
            "last_activity_date" : 1503056264,
            "question_id" : 45753140,
            "link" : "https://stackoverflow.com/questions/45753140/narrator-scan-mode-for-textblock-the-narrator-reads-the-text-properties-twice",
            "title" : "Narrator. Scan mode. For TextBlock the narrator reads the Text properties twice"
        }
    ]
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related