我的方法是對每個Query參數使用UriBuilder和一個字典。然後您可以從每個參數中獲取值UrlEncode,以便您獲得有效的Url。
這是你的代碼是什麼樣子:
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");
這將導致以下鏈接在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
由於StackAPI返回的內容壓縮,對子類WebClient
使用AutomaticDecompression(如here,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;
}
}
,當與其他代碼相結合,對我產生輸出:
{
"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"
}
]
}
這並不是第一個例子工作,但由於某種原因,它適用於'的https:/ /api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#]或[f#]' 你知道它爲什麼適用於此,但不是第一個例子嗎? –
@TimReinagel在您的第一個示例中,'#'用作定位標記,並且一個網址中只能有一個定位標記,因此您的第一個網址無效。在你的第二個例子中'#'是查詢的一部分,所以我們可以對它進行編碼 –
@TimReinagel如果你只想替換'#',我的答案就足夠了。如果你想替換更多的特殊字符,那麼你必須編碼url –