2

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

2 Answers2

1

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"
        }
    ]
}
rene
  • 41,474
  • 78
  • 114
  • 152
0

If # only exists in query part, you can simply do this:

var webAddress = "https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#] OR [java]"
var uri = new Uri(webAddress).AbsoluteUri;
var fixedUri = Regex.Replace(uri, "#", "%23");
39ecneret
  • 661
  • 3
  • 7
  • 17
  • That doesn't work for the first example, but for some reason it works for `https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#] OR [f#]` Do you know why it works for that but not the first example? – Tim Reinagel Aug 18 '17 at 11:20
  • @TimReinagel in your first example, `#` is used as anchor tag and there can be only one anchor tag in one url ,so your first url is invalid. `#` in your second example is part of query so we can encode it – 39ecneret Aug 18 '17 at 11:48
  • @TimReinagel if you only want to replace `#` ,my answer is enough. if you want to replaces more special chars, then you have to encode url – 39ecneret Aug 18 '17 at 11:55
  • No, in the second example it is used as the anchor but when asking for the absolute uri you get the anchor part in addition to the rest of the uri. – Tim Reinagel Aug 18 '17 at 12:26
  • @TimReinagel i have to confirm the second example you refer to is `https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#] OR [java] ` ?? – 39ecneret Aug 18 '17 at 12:49