问题
I have a URL that also might have a query string part, the query string might be empty or have multiple items.
I want to replace one of the items in the query string or add it if the item doesn't already exists.
I have an URI object with the complete URL.
My first idea was to use regex and some string magic, that should do it.
But it seems a bit shaky, perhaps the framework has some query string builder class?
回答1:
Maybe you could use the System.UriBuilder
class. It has a Query
property.
回答2:
I found this was a more elegant solution
var qs = HttpUtility.ParseQueryString(Request.QueryString.ToString());
qs.Set("item", newItemValue);
Console.WriteLine(qs.ToString());
回答3:
Lets have this url:
https://localhost/video?param1=value1
At first update specific query string param to new value:
var uri = new Uri("https://localhost/video?param1=value1");
var qs = HttpUtility.ParseQueryString(uri.Query);
qs.Set("param1", "newValue2");
Next create UriBuilder
and update Query
property to produce new uri with changed param value.
var uriBuilder = new UriBuilder(uri);
uriBuilder.Query = qs.ToString();
var newUri = uriBuilder.Uri;
Now you have in newUri
this value:
https://localhost/video?param1=newValue2
回答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;
This seems to work really well.
回答5:
I use following method:
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();
}
回答6:
No, the framework doesn't have any existing QueryStringBuilder class, but usually the querystring information in a HTTP request is available as an iterable and searchable NameValueCollection
via the Request.Querystring
property.
Since you are starting off with a Uri
object, however, you will need to obtain the querystring portion using the Query
property of the Uri
object. This will yield a string of the form:
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);
You can then split this string on the ampersand character to differentiate it into different querystring parameters-value pairs. Then again split each parameter on the "=" character to differentiate it into a key and value.
Since your final goal is to search for a particular querystring key and if necessary create it, you should try to (re)create a collection (preferably, a generic one) that allows you easily search in the collection, similar to the facility provided by the NameValueCollection
class.
回答7:
I used the following code to append/replace the value of a parameter in the current request 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();
}
Maybe this helps others when finding this topic.
Update:
Just saw the hint about UriBuilder and did a second version using UriBuilder, StringBuilder and 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();
}
回答8:
I agree with Cerebrus. Sticking to the KISS principle, you have the querystring,
string querystring = myURI.Query;
you know what you are looking for and what you want to replace it with.
So use something like this:-
if (querystring == "")
myURI.Query += "?" + replacestring;
else
querystring.replace (searchstring, replacestring); // not too sure of syntax !!
回答9:
I answered a similar question a while ago. Basically, the best way would be to use the class HttpValueCollection
, which the QueryString
property actually is, unfortunately it is internal in the .NET framework.
You could use Reflector to grab it (and place it into your Utils class). This way you could manipulate the query string like a NameValueCollection, but with all the url encoding/decoding issues taken care for you.
HttpValueCollection
extends NameValueCollection
, and has a constructor that takes an encoded query string (ampersands and question marks included), and it overrides a ToString()
method to later rebuild the query string from the underlying collection.
回答10:
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;
}
}
}
回答11:
You can speed up RegExps by precompiling them.
Check out this tutorial
来源:https://stackoverflow.com/questions/772253/replace-item-in-querystring