How to build a query string for a URL in C#?

前端 未结 30 2381
借酒劲吻你
借酒劲吻你 2020-11-22 01:55

A common task when calling web resources from a code is building a query string to including all the necessary parameters. While by all means no rocket science, there are so

相关标签:
30条回答
  • 2020-11-22 02:23

    I wrote some extension methods that I have found very useful when working with QueryStrings. Often I want to start with the current QueryString and modify before using it. Something like,

    var res = Request.QueryString.Duplicate()
      .ChangeField("field1", "somevalue")
      .ChangeField("field2", "only if following is true", true)
      .ChangeField("id", id, id>0)
      .WriteLocalPathWithQuery(Request.Url)); //Uses context to write the path
    

    For more and the source: http://www.charlesrcook.com/archive/2008/07/23/c-extension-methods-for-asp.net-query-string-operations.aspx

    It's basic, but I like the style.

    0 讨论(0)
  • 2020-11-22 02:24

    A quick extension method based version:

    class Program
    {
        static void Main(string[] args)
        {
            var parameters = new List<KeyValuePair<string, string>>
                                 {
                                     new KeyValuePair<string, string>("A", "AValue"),
                                     new KeyValuePair<string, string>("B", "BValue")
                                 };
    
            string output = "?" + string.Join("&", parameters.ConvertAll(param => param.ToQueryString()).ToArray());
        }
    }
    
    public static class KeyValueExtensions
    {
        public static string ToQueryString(this KeyValuePair<string, string> obj)
        {
            return obj.Key + "=" + HttpUtility.UrlEncode(obj.Value);
        }
    }
    

    You could use a where clause to select which parameters get added to the string.

    0 讨论(0)
  • 2020-11-22 02:24

    The query string can be added to a URL by:

    1. create a name value collection object
    2. add the query string items and their values to this object
    3. encode this name value collection object to the url the code is provided in the below link

    https://blog.codingnovice.com/blog

    public ActionResult Create()
    {
        //declaring name value collection object
        NameValueCollection collection = new NameValueCollection();
    
        //adding new value to the name value collection object
        collection.Add("Id1", "wwe323");
        collection.Add("Id2", "454w");
        collection.Add("Id3", "tyt5656");
        collection.Add("Id4", "343wdsd");
    
        //generating query string
        string url = GenerateQueryString(collection);
    
        return View();
    }
    
    private string GenerateQueryString(NameValueCollection collection)
    {
        var querystring = (
            from key in collection.AllKeys
            from value in collection.GetValues(key)
            select string.Format("{0}={1}",
                HttpUtility.UrlEncode(key),
                HttpUtility.UrlEncode(value))
        ).ToArray();
        return "?" + string.Join("&", querystring);
    }
    
    0 讨论(0)
  • 2020-11-22 02:25

    In dotnet core QueryHelpers.AddQueryString() will accept an IDictionary of key-value pairs. To save a few memory allocs and CPU cycles you can use SortedList<,> instead of IDictionary<,>, with an appropriate capacity and items added in sort order...

    var queryParams = new SortedList<string,string>(2);
    queryParams.Add("abc", "val1");
    queryParams.Add("def", "val2");
    
    string requestUri = QueryHelpers.AddQueryString("https://localhost/api", queryParams);
    
    0 讨论(0)
  • 2020-11-22 02:27
    // USAGE
    [TestMethod]
    public void TestUrlBuilder()
    {
        Console.WriteLine(
            new UrlBuilder("http://www.google.com?A=B")
                .AddPath("SomePathName")
                .AddPath("AnotherPathName")
                .SetQuery("SomeQueryKey", "SomeQueryValue")
                .AlterQuery("A", x => x + "C"));
    }
    

    Output:

    http://www.google.com/SomePathName/AnotherPathName?A=BC&SomeQueryKey=SomeQueryValue

    The code; you can all thank me somewhere, somehow :D

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    // By Demetris Leptos
    namespace TheOperator.Foundation.Web
    {
        public class UrlBuilder
        {
            public string Scheme { get; set; }
    
            public string Host { get; set; }
    
            public int? Port { get; set; }
    
            public List<string> Paths { get; set; }
    
            public SortedDictionary<string, string> QueryPairs { get; set; }
    
            public UrlBuilder(string url)
            {
                this.Paths = new List<string>();
                this.QueryPairs = new SortedDictionary<string, string>();
    
                string path = null;
                string query = null;
                Uri relativeUri = null;
                if (!Uri.TryCreate(url, UriKind.Relative, out relativeUri))
                {
                    var uriBuilder = new UriBuilder(url);
                    this.Scheme = uriBuilder.Scheme;
                    this.Host = uriBuilder.Host;
                    this.Port = uriBuilder.Port;
                    path = uriBuilder.Path;
                    query = uriBuilder.Query;
                }
                else
                {
                    var queryIndex = url.IndexOf('?');
                    if (queryIndex >= 0)
                    {
                        path = url.Substring(0, queryIndex);
                        query = url.Substring(queryIndex + 1);
                    }
                    else
                    {
                        path = url;
                    }
                }
                this.Paths.AddRange(path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
                if (query != null)
                {
                    var queryKeyValuePairs = HttpUtility.ParseQueryString(query);
                    foreach (var queryKey in queryKeyValuePairs.AllKeys)
                    {
                        this.QueryPairs[queryKey] = queryKeyValuePairs[queryKey];
                    }
                }
            }
    
            public UrlBuilder AddPath(string value)
            {
                this.Paths.Add(value);
                return this;
            }
    
            public UrlBuilder SetQuery(string key, string value)
            {
                this.QueryPairs[key] = value;
                return this;
            }
    
            public UrlBuilder RemoveQuery(string key)
            {
                this.QueryPairs.Remove(key);
                return this;
            }
    
            public UrlBuilder AlterQuery(string key, Func<string, string> alterMethod, bool removeOnNull = false)
            {
                string value;
                this.QueryPairs.TryGetValue(key, out value);
                value = alterMethod(value);
                if (removeOnNull && value == null)
                {
                    return this.RemoveQuery(key);
                }
                else
                {
                    return this.SetQuery(key, value);
                }
            }
    
            public override string ToString()
            {
                var path = !string.IsNullOrWhiteSpace(this.Host)
                    ? string.Join("/", this.Host, string.Join("/", this.Paths))
                    : string.Join("/", this.Paths);
                var query = string.Join("&", this.QueryPairs.Select(x => string.Concat(x.Key, "=", HttpUtility.UrlEncode(x.Value))));
                return string.Concat(
                    !string.IsNullOrWhiteSpace(this.Scheme) ? string.Concat(this.Scheme, "://") : null,
                    path,
                    !string.IsNullOrWhiteSpace(query) ? string.Concat("?", query) : null);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:28

    If you look under the hood the QueryString property is a NameValueCollection. When I've done similar things I've usually been interested in serialising AND deserialising so my suggestion is to build a NameValueCollection up and then pass to:

    using System.Linq;
    using System.Web;
    using System.Collections.Specialized;
    
    private string ToQueryString(NameValueCollection nvc)
    {
        var array = (
            from key in nvc.AllKeys
            from value in nvc.GetValues(key)
                select string.Format(
                    "{0}={1}",
                    HttpUtility.UrlEncode(key),
                    HttpUtility.UrlEncode(value))
            ).ToArray();
        return "?" + string.Join("&", array);
    }
    

    I imagine there's a super elegant way to do this in LINQ too...

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