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

前端 未结 30 3179
借酒劲吻你
借酒劲吻你 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:43

    With the inspiration from Roy Tinker's comment, I ended up using a simple extension method on the Uri class that keeps my code concise and clean:

    using System.Web;
    
    public static class HttpExtensions
    {
        public static Uri AddQuery(this Uri uri, string name, string value)
        {
            var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
    
            httpValueCollection.Remove(name);
            httpValueCollection.Add(name, value);
    
            var ub = new UriBuilder(uri);
            ub.Query = httpValueCollection.ToString();
    
            return ub.Uri;
        }
    }
    

    Usage:

    Uri url = new Uri("http://localhost/rest/something/browse").
              AddQuery("page", "0").
              AddQuery("pageSize", "200");
    

    Edit - Standards compliant variant

    As several people pointed out, httpValueCollection.ToString() encodes Unicode characters in a non-standards-compliant way. This is a variant of the same extension method that handles such characters by invoking HttpUtility.UrlEncode method instead of the deprecated HttpUtility.UrlEncodeUnicode method.

    using System.Web;
    
    public static Uri AddQuery(this Uri uri, string name, string value)
    {
        var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
    
        httpValueCollection.Remove(name);
        httpValueCollection.Add(name, value);
    
        var ub = new UriBuilder(uri);
    
        // this code block is taken from httpValueCollection.ToString() method
        // and modified so it encodes strings with HttpUtility.UrlEncode
        if (httpValueCollection.Count == 0)
            ub.Query = String.Empty;
        else
        {
            var sb = new StringBuilder();
    
            for (int i = 0; i < httpValueCollection.Count; i++)
            {
                string text = httpValueCollection.GetKey(i);
                {
                    text = HttpUtility.UrlEncode(text);
    
                    string val = (text != null) ? (text + "=") : string.Empty;
                    string[] vals = httpValueCollection.GetValues(i);
    
                    if (sb.Length > 0)
                        sb.Append('&');
    
                    if (vals == null || vals.Length == 0)
                        sb.Append(val);
                    else
                    {
                        if (vals.Length == 1)
                        {
                            sb.Append(val);
                            sb.Append(HttpUtility.UrlEncode(vals[0]));
                        }
                        else
                        {
                            for (int j = 0; j < vals.Length; j++)
                            {
                                if (j > 0)
                                    sb.Append('&');
    
                                sb.Append(val);
                                sb.Append(HttpUtility.UrlEncode(vals[j]));
                            }
                        }
                    }
                }
            }
    
            ub.Query = sb.ToString();
        }
    
        return ub.Uri;
    }
    

提交回复
热议问题