Replace item in querystring

前端 未结 11 1480
甜味超标
甜味超标 2020-12-11 01:23

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

相关标签:
11条回答
  • 2020-12-11 01:39

    Maybe you could use the System.UriBuilder class. It has a Query property.

    0 讨论(0)
  • 2020-12-11 01:39
       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;
           }
       }
    }
    
    0 讨论(0)
  • 2020-12-11 01:50

    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.

    0 讨论(0)
  • 2020-12-11 01:50

    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();
        }
    
    0 讨论(0)
  • 2020-12-11 01:51

    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.

    0 讨论(0)
提交回复
热议问题