C# 如何在没有碎片的情况下创建Uri(将#转换为%23)

C# 如何在没有碎片的情况下创建Uri(将#转换为%23),c#,uri,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?s

我试图通过使用查询字符串进行高级搜索,但当我包含#时,它在创建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#]%20或%20[java]

我该怎么做

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

进入

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

我使用的是.Net Framework 4.6.2

如果
#
仅存在于查询部分,您可以简单地执行以下操作:

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

我的方法是对每个查询参数使用UriBuilder和字典。然后,您可以从每个参数中输入值,以便获得有效的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");
当与其他代码结合时,会为我生成输出:

{
    "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在你的第一个例子中,
#
用作锚定标记,并且一个url中只能有一个锚定标记,因此您的第一个url无效<代码>#在第二个示例中是查询的一部分,因此我们可以进行编码it@TimReinagel如果您只想替换
#
,我的回答就足够了。如果要替换更多特殊字符,则必须对urlNo进行编码,在第二个示例中,它被用作锚定,但当询问绝对uri时,除了uri的其余部分外,您还得到锚定部分。@TimReinagel我必须确认您提到的第二个示例是
https://api.stackexchange.com/2.2/search/advanced?site=stackoverflow&q=[c#]或[java]
??
{
    "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"
        }
    ]
}