在C#中输出操作过的QueryString

23
使用以下代码可以获得一个漂亮格式化的字符串:
Request.QueryString.ToString 

给我类似于:&hello=world&microsoft=sucks 的东西

但是当我使用此代码将集合克隆到另一个对象(相同类型的对象)时,我从 ToString() 方法中得到了 Type() 返回的结果。

System.Collections.Specialized.NameValueCollection variables = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (!string.IsNullOrEmpty(variables["sid"]))
    variables.Remove("sid");
Response.Write(variables.ToString());

除了手动查看并构建字符串,是否有更简洁的输出方式?


10
如果微软像你在例子中写的那样糟糕,为什么你要使用微软的技术? - Patrick Desjardins
12
我只是开玩笑,请冷静。 - Anthony Main
6个回答

69

HttpValueCollection 是内部类,但你可以使用 "var" 关键字声明它,而无需使用反射提取。

var query = HttpUtility.ParseQueryString(Request.Url.Query);
query["Lang"] = myLanguage; // Add or replace param
string myNewUrl = Request.Url.AbsolutePath + "?" + query;

2
不错的想法!但是在这里 var 没有起到任何作用,那只是虚拟方法分派。NameValueCollection values = HttpUtility.ParseQueryString(...) 同样可以工作。此外,我会添加一个注释来解释你正在做什么。 - Ben Challenor
如果需要一个空的查询字符串,HttpUtility.ParseQueryString("") 也可以很好地工作。 - Ben Challenor
+1. 但是为什么不用NameValueCollection而使用var呢?顺便说一下,这对我来说可行。 - Dani Rodríguez
我们可以使用Request.Url.Query或者Request.QueryString.ToString()。我猜测Request.Url.Query的性能更好。这两者之间唯一的区别是Request.Url.Query返回一个问号?,但幸运的是HttpUtility.ParseQueryString()并不在意。 - Jaider
在C#中,var关键字是一种语法糖。NameValueCollection values = ... 和 var values = ... 产生完全相同和相同的IL。var告诉编译器“赋值语句左侧的类型与右侧相同”。 - Thanasis Ioannidis
显示剩余2条评论

8
您也可以使用Reflector将HttpValueCollection类提取到自己的项目中,并在需要时使用它。

我在这里给你胜利,hmemcpy,因为它可能是最合适的,但它并没有解决我的问题,我想我只能用肮脏的方法来解决它。 - Anthony Main
实际上,你只需要使用HttpValueCollection.ToString(bool urlencoded, IDictionary excludeKeys)方法。 - James Curran
是的,就像詹姆斯所说的那样,HttpValueCollection 重写了 ToString() 方法,使用 HttpEncoded 值和 & 符号创建查询字符串。您可以在值上使用 Add/Remove 方法,然后调用 ToString() 方法创建新的查询字符串。 - Igal Tabachnik
你能告诉我关于Reflector的情况吗?它是一种可以查看程序集的软件还是其他什么东西? - Barbaros Alp
1
是的,Reflector可以打开.NET Dll/Exe文件,并进行测试以重现其中的代码。还有一些插件可以让你做其他事情,比如将其反汇编为一个项目。 - Anthony Main

4

这是一个特殊的HTTPValueCollection类型的NVC。因此,当您在其上调用.ToString时,它知道如何正确地格式化它。


2

为什么要将QueryString集合复制到新的NameValueCollection中?

这样做可以使得查询字符串参数更易于处理和操作。通过将其转换为NameValueCollection,您可以使用键值对的方式轻松地访问和修改查询字符串参数。此外,它还提供了一些方便的方法来处理这些参数,例如获取所有键或所有值的列表。
    if (!string.IsNullOrEmpty(Request.QueryString["sid"]))
        Request.QueryString.Remove("sid");

确实,我错了,它是只读的。所以本质上是在您的NameValuecollection上使用Remove方法:

System.Collections.Specialized.NameValueCollection variables = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (!string.IsNullOrEmpty(variables["sid"]))
    variables.Remove("sid");

因为Querystring集合是只读的,所以我无法从中删除。 - Anthony Main

1

如果您并非绝对需要一个NameValueCollection,那么字典(Dictionary)可以提供很多相同的语义:

var variables = Request.QueryString.OfType<DictionaryEntry>()
    .Where(entry => entry.Key != "sid")
    .ToDictionary(entry => entry.Key, entry => entry.Value);

1
我认为这在具有重复键的查询字符串上不起作用。 - Mauricio Scheffer

0

Request.QueryString 实际上返回一个 HttpValueCollection 对象(不幸的是,它是 System.Web 内部的,因此您无法使用它)。

尽管如此,HttpValueCollection 派生自 NameValueCollection,其 Remove() 方法保持完整,因此您应该能够调用 Request.QueryString.Remove("sid");


很遗憾,您无法这样做,因为它是只读集合。 - Anthony Main

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