NameValueCollection URL查询?
我知道我可以做到这一点
var nv = HttpUtility.ParseQueryString(req.RawUrl);
但有没有办法将其转换回url?
var newUrl = HttpUtility.Something("/page", nv);
只需在NameValueCollection
上调用ToString()
,将以name1=value1&name2=value2
查询string就绪格式返回名称值对。 请注意, NameValueCollection
types实际上并不支持这一点,它是误导性的build议,但行为在这里工作,由于实际返回的内部types,如下所述。
感谢@mjwills指出HttpUtility.ParseQueryString
方法实际上返回一个内部的HttpValueCollection
对象,而不是一个常规的NameValueCollection
( 尽pipe文档指定了NameValueCollection
)。 当使用ToString()
, HttpValueCollection
自动对查询string进行编码,因此不需要编写循环遍历集合的例程并使用UrlEncode
方法。 所需的结果已经返回。
结果在手,你可以把它附加到URL并redirect:
var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString()); string url = Request.Url.AbsolutePath + "?" + nameValues.ToString(); Response.Redirect(url);
目前使用HttpValueCollection
的唯一方法是使用上面显示的ParseQueryString
方法(当然除了reflection)。 看起来这不会改变,因为请求这个类的连接问题被公开已经被closures,状态是“不会修复”。
另外,您可以调用nameValues
上的Add
, Set
和Remove
方法来修改任何查询string项目,然后再附加它。 如果您对此感兴趣, 请参阅我对另一个问题的回答 。
string q = String.Join("&", nvc.AllKeys.Select(a => a + "=" + HttpUtility.UrlEncode(nvc[a])));
其实,你也应该把密钥编码,而不仅仅是价值。
string q = String.Join("&", nvc.AllKeys.Select(a => $"{HttpUtility.UrlEncode(a)}={HttpUtility.UrlEncode(nvc[a])}"));
做一个使用几个循环的扩展方法。 我喜欢这个解决scheme,因为它是可读的(没有LINQ),不需要System.Web.HttpUtility并处理重复的键。
public static string ToQueryString(this NameValueCollection nvc) { StringBuilder sb = new StringBuilder(); foreach (string key in nvc.Keys) { if (string.IsNullOrEmpty(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(); }
例
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());
产量
?order_id=0000&item_id=1111&item_id=2222&needs%20escaping=special%20chars%20%3F%20%3D%20%26
简短的答案是在NameValueCollection
上使用.ToString()
,并将其与原始URL结合起来。
不过,我想指出一些事情:
你不能使用Request.RawUrl
HttpUtility.ParseQueryString
。 ParseQueryString()
方法正在寻找这样的值: ?var=value&var2=value2
。
如果你想获得QueryString
参数的NameValueCollection
,只需使用Request.QueryString()
。
var nv = Request.QueryString;
重buildURL只需使用nv.ToString()。
string url = String.Format("{0}?{1}", Request.Path, nv.ToString());
如果您尝试parsingurlstring而不是使用Request
对象, Request
使用Uri
和HttpUtility.ParseQueryString
方法。
Uri uri = new Uri("<THE URL>"); var nv = HttpUtility.ParseQueryString(uri.Query); string url = String.Format("{0}?{1}", uri.AbsolutePath, nv.ToString());
因为一个NameValueCollection
对于同一个键可以有多个值,所以如果你关心查询string的格式(因为它会以逗号分隔的值而不是“数组符号”的forms返回),你可以考虑下面的内容。
例
var nvc = new NameValueCollection(); nvc.Add("key1", "val1"); nvc.Add("key2", "val2"); nvc.Add("empty", null); nvc.Add("key2", "val2b");
转入: 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) ); }) );
或者如果你不喜欢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); } } } }
正如已经在评论中指出的那样,除了这个答案以外,大多数其他答案都是针对场景( Request.QueryString
是一个HttpValueCollection
,而不是“ NameValueCollection
)而不是字面问题。
更新:从评论中解决空值问题。
这会为你工作吗?
public static string BuildUrl(string relativeUrl, params string[] queryString) { // build queryString from string parameters char[] trimChars = { ' ', '&', '?' }; StringBuilder builder = new StringBuilder(); string sepChar = "&"; string sep = String.Empty; foreach (string q in queryString) { builder.Append(sep).Append(q.Trim(trimChars)); sep = sepChar; } if (String.IsNullOrEmpty(builder.ToString())) { return relativeUrl; } else { return relativeUrl + "?" + builder.ToString(); } }
使用:
string url = BuildUrl("/mypage.apsx", "qs1=a", "qs2=b", "qs3=c");
这应该没有太多的代码工作:
NameValueCollection nameValues = HttpUtility.ParseQueryString(String.Empty); nameValues.Add(Request.QueryString); // modify nameValues if desired var newUrl = "/page?" + nameValues;
这个想法是使用HttpUtility.ParseQueryString
来生成一个types为HttpValueCollection
。 这个类是NameValueCollection
一个子类,被标记为internal
所以你的代码不能轻易地创build它的一个实例。
HttpValueCollection
在于ToString
方法为你编码。 通过利用NameValueCollection.Add(NameValueCollection)
方法,您可以将现有的查询string参数添加到新创build的对象,而不必先将Request.QueryString
集合转换为url编码的string,然后将其parsing回集合中。
这种技术也可以作为扩展方法公开:
public static string ToQueryString(this NameValueCollection nameValueCollection) { NameValueCollection httpValueCollection = HttpUtility.ParseQueryString(String.Empty) httpValueCollection.Add(nameValueCollection); return httpValueCollection.ToString(); }
您可以使用。
var ur = new Uri("/page",UriKind.Relative);
如果这个nv是stringtypes,你可以追加到uri的第一个参数。 喜欢
var ur2 = new Uri("/page?"+nv.ToString(),UriKind.Relative);
我总是使用UriBuilder将具有查询string的url转换回有效且正确编码的url。
var url = "http://my-link.com?foo=bar"; var uriBuilder = new UriBuilder(url); var query = HttpUtility.ParseQueryString(uriBuilder.Query); query.Add("yep", "foo&bar"); uriBuilder.Query = query.ToString(); var result = uriBuilder.ToString(); // http://my-link.com:80/?foo=bar&yep=foo%26bar
- types是在未引用的程序集中定义的,如何find原因?
- 如何将双引号添加到variables内的string?
- 我如何循环浏览date范围?
- EXECUTE权限在用户定义的表types上被拒绝?
- 如何使用WebRequest发布数据并从网页获取响应
- 您对Windows Workflow Foundation有什么经验?
- 从数据注释的Asp.Net Mvc隐藏字段
- Visual Studio“无法在Web服务器上启动debugging。 networking服务器没有及时回应。“
- Web部署任务失败。 (“Microsoft.Web.Deployment.DeploymentManager”的types初始值设定项引发exception。)