2017-08-18 70 views
2

我試圖通過使用查詢字符串進行高級搜索,但是當我包含#它在創建uri時未轉換爲%23。如何在沒有碎片的情況下創建Uri(將#轉換爲%23)

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

當我這樣做時,會引發異常。 當我只包含一個#符號時,它將它分割。就像這個例子

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

烏里現在等於

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

如何使

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

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

我使用.NET Framework 4.6.2

回答

1

我的方法是對每個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(如hereferoze ):

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" 
     } 
    ] 
} 
0

如果#只有在查詢部分存在,你可以簡單地這樣做:

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"); 
+0

這並不是第一個例子工作,但由於某種原因,它適用於'的https:/ /api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#]或[f#]' 你知道它爲什麼適用於此,但不是第一個例子嗎? –

+0

@TimReinagel在您的第一個示例中,'#'用作定位標記,並且一個網址中只能有一個定位標記,因此您的第一個網址無效。在你的第二個例子中'#'是查詢的一部分,所以我們可以對它進行編碼 –

+0

@TimReinagel如果你只想替換'#',我的答案就足夠了。如果你想替換更多的特殊字符,那麼你必須編碼url –

相關問題