69 asp.net url namevaluecollection url-encoding
我知道我能做到这一点
var nv = HttpUtility.ParseQueryString(req.RawUrl);
Run Code Online (Sandbox Code Playgroud)
但有没有办法将其转换回网址?
var newUrl = HttpUtility.Something("/page", nv);
Run Code Online (Sandbox Code Playgroud)
Ahm*_*eed 104
只需调用ToString()
它NameValueCollection
就会以name1=value1&name2=value2
querystring ready格式返回名称值对.请注意,NameValueCollection
类型实际上并不支持这种情况,并且建议这样做会产生误导,但由于实际返回的内部类型,此行为在此处起作用,如下所述.
感谢@mjwills指出该HttpUtility.ParseQueryString
方法实际上返回的是内部HttpValueCollection
对象而不是常规对象NameValueCollection
(尽管文档指定NameValueCollection
).使用时会HttpValueCollection
自动对查询字符串进行编码ToString()
,因此无需编写循环遍历集合并使用该UrlEncode
方法的例程.已返回所需的结果.
有了结果,您可以将其附加到URL并重定向:
var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());
string url = Request.Url.AbsolutePath + "?" + nameValues.ToString();
Response.Redirect(url);
Run Code Online (Sandbox Code Playgroud)
目前使用a的唯一方法HttpValueCollection
是使用ParseQueryString
上面显示的方法(当然不是反射).看起来这不会改变,因为请求此类公开的Connect问题已关闭,状态为"将无法修复".
顺便说一句,你可以调用Add
,Set
以及Remove
对方法nameValues
,以追加之前修改任何查询字符串的项目.如果您对此感兴趣,请参阅我对其他问题的回复.
Den*_*nis 63
string q = String.Join("&",
nvc.AllKeys.Select(a => a + "=" + HttpUtility.UrlEncode(nvc[a])));
Run Code Online (Sandbox Code Playgroud)
Mat*_*ger 14
创建一个使用几个循环的扩展方法.我更喜欢这个解决方案,因为它是可读的(没有linq),不需要System.Web.HttpUtility,它处理重复的键.
public static string ToQueryString(this NameValueCollection nvc)
{
if (nvc == null) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string key in nvc.Keys)
{
if (string.IsNullOrWhiteSpace(key)) continue;
string[] values = nvc.GetValues(key);
if (values == null) continue;
foreach (string value in values)
{
sb.Append(sb.Length == 0 ? "?" : "&");
sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
}
}
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
var queryParams = new NameValueCollection()
{
{ "order_id", "0000" },
{ "item_id", "1111" },
{ "item_id", "2222" },
{ null, "skip entry with null key" },
{ "needs escaping", "special chars ? = &" },
{ "skip entry with null value", null }
};
Console.WriteLine(queryParams.ToQueryString());
Run Code Online (Sandbox Code Playgroud)
?order_id=0000&item_id=1111&item_id=2222&needs%20escaping=special%20chars%20%3F%20%3D%20%26
Run Code Online (Sandbox Code Playgroud)
dan*_*ana 12
这应该没有太多代码:
NameValueCollection nameValues = HttpUtility.ParseQueryString(String.Empty);
nameValues.Add(Request.QueryString);
// modify nameValues if desired
var newUrl = "/page?" + nameValues;
Run Code Online (Sandbox Code Playgroud)
这个想法是用来HttpUtility.ParseQueryString
生成一个空的类型集合HttpValueCollection
.此类是其子类NameValueCollection
,标记为internal
您的代码无法轻松创建它的实例.
好处HttpValueCollection
是该ToString
方法为您处理编码.通过利用该NameValueCollection.Add(NameValueCollection)
方法,您可以将现有的查询字符串参数添加到新创建的对象中,而无需先将Request.QueryString
集合转换为url编码的字符串,然后将其解析回集合.
此技术也可以作为扩展方法公开:
public static string ToQueryString(this NameValueCollection nameValueCollection)
{
NameValueCollection httpValueCollection = HttpUtility.ParseQueryString(String.Empty);
httpValueCollection.Add(nameValueCollection);
return httpValueCollection.ToString();
}
Run Code Online (Sandbox Code Playgroud)
因为NameValueCollection
同一个键可以有多个值,所以如果您关心查询字符串的格式(因为它将作为逗号分隔值而不是“数组表示法”返回),您可以考虑以下内容。
var nvc = new NameValueCollection();
nvc.Add("key1", "val1");
nvc.Add("key2", "val2");
nvc.Add("empty", null);
nvc.Add("key2", "val2b");
Run Code Online (Sandbox Code Playgroud)
变成:key1=val1&key2[]=val2&empty&key2[]=val2b
而不是key1=val1&key2=val2,val2b&empty
。
string qs = string.Join("&",
// "loop" the keys
nvc.AllKeys.SelectMany(k => {
// "loop" the values
var values = nvc.GetValues(k);
if(values == null) return new[]{ k };
return nvc.GetValues(k).Select( (v,i) =>
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(v), i)
);
})
);
Run Code Online (Sandbox Code Playgroud)
或者如果你不太喜欢 Linq...
string qs = nvc.ToQueryString(); // using...
public static class UrlExtensions {
public static string ToQueryString(this NameValueCollection nvc) {
return string.Join("&", nvc.GetUrlList());
}
public static IEnumerable<string> GetUrlList(this NameValueCollection nvc) {
foreach(var k in nvc.AllKeys) {
var values = nvc.GetValues(k);
if(values == null) { yield return k; continue; }
for(int i = 0; i < values.Length; i++) {
yield return
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(values[i]), i);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如评论中已经指出的那样,除了这个答案之外,大多数其他答案都解决了场景(Request.QueryString
是一个HttpValueCollection
,“不是”a NameValueCollection
)而不是字面问题。
更新:解决了评论中的空值问题。
小智 5
实际上,你也应该对键进行编码,而不仅仅是值.
string q = String.Join("&",
nvc.AllKeys.Select(a => $"{HttpUtility.UrlEncode(a)}={HttpUtility.UrlEncode(nvc[a])}"));
Run Code Online (Sandbox Code Playgroud)
Gab*_*ães -2
您可以使用。
var ur = new Uri("/page",UriKind.Relative);
Run Code Online (Sandbox Code Playgroud)
如果此 nv 是字符串类型,您可以附加到 uri 第一个参数。喜欢
var ur2 = new Uri("/page?"+nv.ToString(),UriKind.Relative);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
44305 次 |
最近记录: |