如何使用C#解析包含"&"符号的查询字符串值?

5

我有一个C#自定义WebPart放置在SharePoint 2007页面上。当在另一页的SSRS报表中点击链接时,会通过查询字符串将用户发送到我的自定义WebPart页面,例如下面这样:

?tax4Elem=Docks%20&%20Chargers&ss=EU%20MOVEX&Phase=1&tax3Elem=Play%20IT&tax5Elem=Charger

请注意“tax4Elem”字段的值,它基本上是“Docks&Chargers”。 (和号实际上可能出现在“tax4Elem”,“tax3Elem”和“tax5Elem”中)。
我不能对该值中的和号进行编码,因此必须处理此问题。
我应该如何解析此查询字符串,以便不将“Docks&Chargers”中的“&”识别为键/值对的开始?
谢谢! 凯特

3
好的,看起来这个URL的编码有问题...我可以尝试找出谁能够更正这个问题,并在SSRS报告中显示%26。非常感谢您的时间! - KateF
最终,我使用了一个工具来帮助我创建正则表达式,现在它看起来像这样:'Regex.Split(qstr, @"(?<=\w)&(?=\w)")',然后我又必须在"="上再次拆分它,以获取我的键/值对。 - KateF
4个回答

1

显然请求是不正确的。但是,为了解决这个问题,您可以获取原始URL,然后找到&ss=的IndexOf。然后,在那之前找到=符号。对=&ss=之间的部分进行解码(使用UrlDecode),然后重新编码(使用UrlEncode)(tax4Elem的值)。然后,像这样重构查询字符串:

correctQueryString = "?tax4Elem=" + reencodedTaxValue + remainderOfQueryString

并将其正常解码(例如使用{{link1:ParseQueryString}})成一个NameValueCollection

可能可以行得通,但是tax3Elem和tax5Elem的值中也可能有同样的问题。 - KateF
@Kate,如果它们都可能是错误的,那么你必须迭代地执行此过程。在那时,我会编写一个自定义解析器,而不是尝试使用ParseQueryString - Matthew Flaschen
哎呀...我以为会有一些很酷的正则表达式可以解决这个问题。我试过了,但是正则表达式从来不是我的强项。:-/ 谢谢。 - KateF
@Kate,假设它们都以tax开头,你可以使用tax\w.*?=找到键的位置。如果不是这样,你可以做类似于(?:tax|otherPrefix)\w.*?=的事情。当你有了键的位置,值就在它们之间。我认为你可以为此创建一个组。类似于(?:tax|otherPrefix)\w.*?=(.*?),但这个还没有经过测试。 - Matthew Flaschen
谢谢你为我提供正则表达式的良好起点,我会尝试类似的方法。 - KateF
@Kate,没问题。上面的所有\w.都可以改成\w。保留句号是疏忽。 - Matthew Flaschen

1

如果您真的无法更正URL,仍然可以尝试解析它,但您必须做出一些决策。例如:

  • 键只能包含字母数字字符。
  • 没有空值,或者至少在键后总是有一个等号=
  • 值可能包含其他的&和?。
  • 值可能包含其他的等号,只要它们不是新的键/值对的一部分(它们没有前缀&\w+

捕获这些键值对的一种可能的方法是:

MatchCollection matches = Regex.Matches(s, @"\G[?&](?<Key>\w+)=(?<Value>.*?(?=$|&\w+=))");
var values = matches.Cast<Match>()
                    .ToDictionary(m => m.Groups["Key"].Value,
                                  m => HttpUtility.UrlDecode(m.Groups["Value"].Value),
                                  StringComparer.OrdinalIgnoreCase);

你可以获取这些值:
string tax4 = values["tax4Elem"];

请注意,如果查询字符串根据我们的规则是“无效”的,则该模式可能无法捕获所有值。

哇...太棒了...我现在就去试试。谢谢! - KateF
这个似乎使用了 LinQ 注释,而我们没有使用...如果不使用 LinQ,完成相同的事情的过程是什么? - KateF
@KateF - 这里唯一使用的LINQ是ToDictionary扩展方法。您可以循环遍历匹配项并将它们添加到字典或键/值集合中 - 这里没有任何魔法...(顺便说一下,这是.NET 3.5,由SharePoint 2007支持。) - Kobi

1

我认为你无法正确解析该字符串 - 它已被错误编码。在“Docks&Chargers”中的“&”应该被编码为%26而不是&

?tax4Elem=Docks%20%26%20Chargers&ss=EU%20MOVEX&Phase=1&tax3Elem=Play%20IT&tax5Elem=Charger

是否有可能更改生成URL的代码?


很不幸,我无法对其进行编码...该值来自外部数据库,并被吸入到一个我无法控制的 SSRS 报告中。那么我是否需要通过基本字符串操作来解析这个字符串呢? - KateF

-1

或者您可以使用 HttpServerUtility.HtmlDecode 方法将该值解码为 '&'(和号)符号。


它一开始就没有在字符串中编码,这是无效的并导致了原始问题。 - Matthew Flaschen
我明白了,我的错,我没有注意到那个&符号! - Waqas
我觉得你想表达的是HttpServerUtility.HtmlEncode(我找不到任何“HtmlDecode”),但如果我不对正确使用的“&”进行编码,我该如何使用它来指示下一个键/值对? - KateF
1
另外,HtmlDecode 是错误的方法。它将 &lt; 转换为 < - Matthew Flaschen

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