如何创建没有碎片的Uri(将#转换为%23)

时间:2017-08-18 10:19:40

标签: c# uri

我正在尝试使用查询字符串进行高级搜索,但是当我包含#时,在创建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;

Uri现在等于

  

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

2 个答案:

答案 0 :(得分:1)

我的方法是为每个Query参数使用UriBuilder和Dictionary。然后,您可以UrlEncode每个参数的值,以便获得有效的网址。

这就是您的代码的样子:

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

答案 1 :(得分: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");