替换查询字符串中的项目

我有一个URL也可能有一个查询字符串部分,查询字符串可能是空的或有多个项目。

我想替换查询字符串中的一个项目,或者如果该项目尚不存在则添加它。

我有一个带有完整URL的URI对象。

我的第一个想法是使用正则表达式和一些字符串魔法,应该这样做。

但它似乎有点摇摇欲坠,也许框架有一些查询字符串构建器类?

也许你可以使用System.UriBuilder类。 它有一个Query属性。

我发现这是一个更优雅的解决方案

 var qs = HttpUtility.ParseQueryString(Request.QueryString.ToString()); qs.Set("item", newItemValue); Console.WriteLine(qs.ToString()); 

让我们有这个url: https://localhost/video?param1=value1

首先将特定查询字符串参数更新为新值:

 var uri = new Uri("https://localhost/video?param1=value1"); var qs = HttpUtility.ParseQueryString(uri.Query); qs.Set("param1", "newValue2"); 

接下来创建UriBuilder并更新Query属性以生成具有更改的param值的新uri。

 var uriBuilder = new UriBuilder(uri); uriBuilder.Query = qs.ToString(); var newUri = uriBuilder.Uri; 

现在你在newUri这个值: https://localhost/video?param1=newValue2

 string link = page.Request.Url.ToString(); if(page.Request.Url.Query == "") link += "?pageIndex=" + pageIndex; else if (page.Request.QueryString["pageIndex"] != "") { var idx = page.Request.QueryString["pageIndex"]; link = link.Replace("pageIndex=" + idx, "pageIndex=" + pageIndex); } else link += "&pageIndex=" + pageIndex; 

这似乎工作得很好。

我使用以下方法:

  public static string replaceQueryString(System.Web.HttpRequest request, string key, string value) { System.Collections.Specialized.NameValueCollection t = HttpUtility.ParseQueryString(request.Url.Query); t.Set(key, value); return t.ToString(); } 

不,该框架没有任何现有的QueryStringBuilder类,但通常HTTP请求中的查询字符串信息可通过Request.Querystring属性作为可迭代和可搜索的NameValueCollection提供。

但是,由于您是从Uri对象开始的,因此需要使用Uri对象的Query属性获取查询字符串部分。 这将产生一个forms的字符串:

 Uri myURI = new Uri("http://www.mywebsite.com/page.aspx?Val1=A&Val2=B&Val3=C"); string querystring = myURI.Query; // Outputs: "?Val1=A&Val2=B&Val3=C". Note the ? prefix! Console.WriteLine(querystring); 

然后,您可以在&符号上拆分此字符串,以将其区分为不同的查询字符串参数 – 值对。 然后再次拆分“=”字符上的每个参数,将其区分为键和值。

由于您的最终目标是搜索特定的查询字符串密钥并在必要时创建它,您应该尝试(重新)创建一个集合(最好是通用集合),以便您轻松搜索集合,类似于由NameValueCollection类。

我使用以下代码在当前请求URL中追加/替换参数的值:

  public static string CurrentUrlWithParam(this UrlHelper helper, string paramName, string paramValue) { var url = helper.RequestContext.HttpContext.Request.Url; var sb = new StringBuilder(); sb.AppendFormat("{0}://{1}{2}{3}", url.Scheme, url.Host, url.IsDefaultPort ? "" : ":" + url.Port, url.LocalPath); var isFirst = true; if (!String.IsNullOrWhiteSpace(url.Query)) { var queryStrings = url.Query.Split(new[] { '?', ';' }); foreach (var queryString in queryStrings) { if (!String.IsNullOrWhiteSpace(queryString) && !queryString.StartsWith(paramName + "=")) { sb.AppendFormat("{0}{1}", isFirst ? "?" : ";", queryString); isFirst = false; } } } sb.AppendFormat("{0}{1}={2}", isFirst ? "?" : ";", paramName, paramValue); return sb.ToString(); } 

也许这有助于其他人找到这个话题。

更新:

刚看到UriBuilder的提示,并使用UriBuilder,StringBuilder和Linq做了第二个版本:

  public static string CurrentUrlWithParam(this UrlHelper helper, string paramName, string paramValue) { var url = helper.RequestContext.HttpContext.Request.Url; var ub = new UriBuilder(url.Scheme, url.Host, url.Port, url.LocalPath); // Query string var sb = new StringBuilder(); var isFirst = true; if (!String.IsNullOrWhiteSpace(url.Query)) { var queryStrings = url.Query.Split(new[] { '?', ';' }); foreach (var queryString in queryStrings.Where(queryString => !String.IsNullOrWhiteSpace(queryString) && !queryString.StartsWith(paramName + "="))) { sb.AppendFormat("{0}{1}", isFirst ? "" : ";", queryString); isFirst = false; } } sb.AppendFormat("{0}{1}={2}", isFirst ? "" : ";", paramName, paramValue); ub.Query = sb.ToString(); return ub.ToString(); } 

我同意Cerebrus。 坚持KISS原则,你有querystring,

 string querystring = myURI.Query; 

你知道你在寻找什么以及你想要用它替换它。

所以使用这样的东西: –

 if (querystring == "") myURI.Query += "?" + replacestring; else querystring.replace (searchstring, replacestring); // not too sure of syntax !! 

我刚才回答了类似的问题 。 基本上,最好的方法是使用类HttpValueCollection ,它实际上是QueryString属性,不幸的是它在.NET框架中是内部的。 您可以使用Reflector来抓取它(并将其放入Utils类中)。 这样您就可以像NameValueCollection一样操纵查询字符串,但是所有的url编码/解码问题都会得到照顾。

HttpValueCollection扩展了NameValueCollection ,并且具有一个构造函数,该构造函数接受编码的查询字符串(包括&符号和问号),并且它会覆盖ToString()方法,以便稍后从底层集合重建查询字符串。

  public class QueryParams : Dictionary { private Uri originolUrl; private Uri ammendedUrl; private string schemeName; private string hostname; private string path; public QueryParams(Uri url) { this.originolUrl = url; schemeName = url.Scheme; hostname = url.Host; path = url.AbsolutePath; //check uri to see if it has a query if (url.Query.Count() > 1) { //we grab the query and strip of the question mark as we do not want it attached string query = url.Query.TrimStart("?".ToArray()); //we grab each query and place them into an array string[] parms = query.Split("&".ToArray()); foreach (string str in parms) { // we split each query into two strings(key) and (value) and place into array string[] param = str.Split("=".ToArray()); //we add the strings to this dictionary this.Add(param[0], param[1]); } } } public QueryParams Set(string paramName, string value) { if(this.ContainsKey(paramName)) { //if key exists change value this[paramName] = value; return (this); } else { this.Add(paramName, value); return this; } } public QueryParams Set(string paramName, int value) { if (this.ContainsKey(paramName)) { //if key exists change value this[paramName] = value.ToString(); return (this); } else { this.Add(paramName, value); return this; } } public void Add(string key, int value) { //overload, adds a new keypair string strValue = value.ToString(); this.Add(key, strValue); } public override string ToString() { StringBuilder queryString = new StringBuilder(); foreach (KeyValuePair pair in this) { //we recreate the query from each keypair queryString.Append(pair.Key + "=" + pair.Value + "&"); } //trim the end of the query string modifiedQuery = queryString.ToString().TrimEnd("&".ToArray()); if (this.Count() > 0) { UriBuilder uriBuild = new UriBuilder(schemeName, hostname); uriBuild.Path = path; uriBuild.Query = modifiedQuery; ammendedUrl = uriBuild.Uri; return ammendedUrl.AbsoluteUri; } else { return originolUrl.ToString(); } } public Uri ToUri() { this.ToString(); return ammendedUrl; } } } 

您可以通过预编译来加速RegExps。

看看这个教程