我有一个也可能有查询字符串部分的URL,查询字符串可能为空或有多个项目。
我想替换查询字符串中的一个项目,或者如果该项目尚不存在则添加它。
我有一个带有完整网址的URI对象。
我的第一个想法是使用正则表达式和一些字符串魔法,应该这样做。
但是看起来有点不稳定,或许框架有一些查询字符串构建器类?
答案 0 :(得分:42)
我发现这是一个更优雅的解决方案
var qs = HttpUtility.ParseQueryString(Request.QueryString.ToString());
qs.Set("item", newItemValue);
Console.WriteLine(qs.ToString());
答案 1 :(得分:17)
让我们有这个网址:
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
属性以生成具有更改的参数值的新uri。
var uriBuilder = new UriBuilder(uri);
uriBuilder.Query = qs.ToString();
var newUri = uriBuilder.Uri;
现在你有newUri
这个值:
https://localhost/video?param1=newValue2
答案 2 :(得分:4)
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;
这看起来效果很好。
答案 3 :(得分:4)
我使用以下方法:
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();
}
答案 4 :(得分:3)
不,框架没有任何现有的QueryStringBuilder类,但通常HTTP请求中的查询字符串信息可通过NameValueCollection
属性以可迭代和可搜索的Request.Querystring
形式提供。
但是,由于您开始使用Uri
对象,因此需要使用Query
对象的Uri
属性获取查询字符串部分。这将产生一个形式的字符串:
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
班提供。
答案 5 :(得分:3)
也许你可以使用System.UriBuilder
课程。它有Query
属性。
答案 6 :(得分:2)
我使用以下代码追加/替换当前请求网址中的参数值:
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();
}
答案 7 :(得分:1)
我同意Cerebrus。坚持KISS原则,你有查询字符串,
string querystring = myURI.Query;
你知道你在寻找什么,以及你想用它替换它。
所以使用这样的东西: -
if (querystring == "")
myURI.Query += "?" + replacestring;
else
querystring.replace (searchstring, replacestring); // not too sure of syntax !!
答案 8 :(得分:0)
我前一回答similar question。基本上,最好的方法是使用HttpValueCollection
属性实际所在的类QueryString
,不幸的是它是.NET框架内部的。
您可以使用Reflector来抓取它(并将其放入Utils类中)。这样您就可以像NameValueCollection一样操纵查询字符串,但是所有的url编码/解码问题都会得到照顾。
HttpValueCollection
扩展NameValueCollection
,并且有一个构造函数,它接受一个编码的查询字符串(包含&符号和问号),并覆盖ToString()
方法以便稍后重建查询字符串基础集合。
答案 9 :(得分:0)
public class QueryParams : Dictionary<string,string>
{
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<string, string> 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;
}
}
}
答案 10 :(得分:-2)
您可以通过预编译来加速RegExps。
查看此tutorial