如何在C#中正确解析包含“&”的查询字符串?

3

我需要解析查询字符串:?artist=singer1 & singer2&song=name song

如果值包含像 "singer1 & singer2" 这样的与号,静态方法 HttpUtility.ParseQueryString 的工作方式不符合我的要求。

例如:

string qs = "?artist=singer1 & singer2&song=name song"; 
NameValueCollection query = HttpUtility.ParseQueryString(qs);

结果如下:

  1. 艺术家 = 歌手1
  2. null = 歌手2
  3. 歌曲 = 歌名

我想要结果。

artist = singer 1 & singer2
song = name song

有什么想法吗?

12
HttpUtility.ParseQueryString 可以正常工作,你的查询字符串不正确,每个参数必须同时有名称和值。 - Alex
2
实际上,&singer2& 应该被解析为 singer2=<empty>,而不是相反。 - Lasse V. Karlsen
你所说的“不正常”是什么意思?查询字符串由两部分组成,例如“artist=singer”,而你的“singer2”没有第一部分,这就是为什么它是null - robasta
1
@cdhowie 实际上,似乎 HttpUtility 解析错误,它确实将其命名为 null - Lasse V. Karlsen
@LasseV.Karlsen 哈哈,这相当奇怪... - cdhowie
显示剩余6条评论
3个回答

16

你的值中间的和号(&)是保留符号,会干扰解析器。取而代之地应该使用它的数字代码:

string qs = "?artist=singer1+%26+singer2&song=name song"; 
NameValueCollection query = HttpUtility.ParseQueryString(qs);

谢谢,客户端应用程序发送了错误的查询字符串给我。 - misak
如何在C#中构建URL的查询字符串?是复制构建URL的代码的好地方。 - Alexei Levenkov

6
你的问题在于,在查询字符串中,&具有特殊含义,即用于分隔参数。你所认为的artist参数中间的&实际上被解析为一个参数分隔符。在构建URL时,你需要对&进行URL编码。
例如,一个正确的查询字符串应该是:
?artist=singer1+%26+singer2&song=name+song

(空格通常可以编码为+%20,但这是另一个讨论的话题。)
在构建查询字符串组件时,您可以使用HttpUtility.UrlEncode()来确保结果得到正确转义。例如,您可以像这样构建查询字符串:
static void Main()
{
    var values = new NameValueCollection();
    values["artist"] = "singer1 & singer2";
    values["song"] = "name song";

    Console.WriteLine(CreateQueryString(values));
}

static string CreateQueryString(NameValueCollection values)
{
    if (values == null) { throw new ArgumentNullException("values"); }

    return string.Join(
        "&",
        values.AllKeys.Select(key => HttpUtility.UrlEncode(key) + "=" +
                                     HttpUtility.UrlEncode(values[key]))
                      .ToArray());
}

换句话说,问题出现在构建查询字符串的时候,而不是解析它的时候。当你解析它时,你已经有了一个语义不正确的查询字符串;此时你无法做任何事情。

0
如果你想让 artist = singer1 & singer2,你需要在查询字符串中转义或编码&
例如,如果我向 Google 查询 fred & blotts,则生成的查询字符串包含&q=fred+%26+blotts而不是&q=fred+&+blotts
请参见https://www.rfc-editor.org/rfc/rfc3986#page-12

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接