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

前端 未结 30 2921
借酒劲吻你
借酒劲吻你 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: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 Paths { get; set; }
    
            public SortedDictionary QueryPairs { get; set; }
    
            public UrlBuilder(string url)
            {
                this.Paths = new List();
                this.QueryPairs = new SortedDictionary();
    
                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 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);
            }
        }
    }
    

提交回复
热议问题