NameValueCollection to URL Query?

前端 未结 12 2043
温柔的废话
温柔的废话 2020-11-28 05:36

I know i can do this

var nv = HttpUtility.ParseQueryString(req.RawUrl);

But is there a way to convert this back to a url?

v         


        
相关标签:
12条回答
  • 2020-11-28 06:04

    This did the trick for me:

    public ActionResult SetLanguage(string language = "fr_FR")
            {            
                Request.UrlReferrer.TryReadQueryAs(out RouteValueDictionary parameters);            
                parameters["language"] = language;            
                return RedirectToAction("Index", parameters);            
            }
    
    0 讨论(0)
  • 2020-11-28 06:13
    string q = String.Join("&",
                 nvc.AllKeys.Select(a => a + "=" + HttpUtility.UrlEncode(nvc[a])));
    
    0 讨论(0)
  • 2020-11-28 06:13

    In AspNet Core 2.0 you can use QueryHelpers AddQueryString method.

    0 讨论(0)
  • 2020-11-28 06:14

    Because a NameValueCollection can have multiple values for the same key, if you are concerned with the format of the querystring (since it will be returned as comma-separated values rather than "array notation") you may consider the following.

    Example

    var nvc = new NameValueCollection();
    nvc.Add("key1", "val1");
    nvc.Add("key2", "val2");
    nvc.Add("empty", null);
    nvc.Add("key2", "val2b");
    

    Turn into: key1=val1&key2[]=val2&empty&key2[]=val2b rather than key1=val1&key2=val2,val2b&empty.

    Code

    string qs = string.Join("&", 
        // "loop" the keys
        nvc.AllKeys.SelectMany(k => {
            // "loop" the values
            var values = nvc.GetValues(k);
            if(values == null) return new[]{ k };
            return nvc.GetValues(k).Select( (v,i) => 
                // 'gracefully' handle formatting
                // when there's 1 or more values
                string.Format(
                    values.Length > 1
                        // pick your array format: k[i]=v or k[]=v, etc
                        ? "{0}[]={1}"
                        : "{0}={1}"
                    , k, HttpUtility.UrlEncode(v), i)
            );
        })
    );
    

    or if you don't like Linq so much...

    string qs = nvc.ToQueryString(); // using...
    
    public static class UrlExtensions {
        public static string ToQueryString(this NameValueCollection nvc) {
            return string.Join("&", nvc.GetUrlList());
        }
    
        public static IEnumerable<string> GetUrlList(this NameValueCollection nvc) {
            foreach(var k in nvc.AllKeys) {
                var values = nvc.GetValues(k);
                if(values == null)  { yield return k; continue; }
                for(int i = 0; i < values.Length; i++) {
                    yield return
                    // 'gracefully' handle formatting
                    // when there's 1 or more values
                    string.Format(
                        values.Length > 1
                            // pick your array format: k[i]=v or k[]=v, etc
                            ? "{0}[]={1}"
                            : "{0}={1}"
                        , k, HttpUtility.UrlEncode(values[i]), i);
                }
            }
        }
    }
    

    As has been pointed out in comments already, with the exception of this answer most of the other answers address the scenario (Request.QueryString is an HttpValueCollection, "not" a NameValueCollection) rather than the literal question.

    Update: addressed null value issue from comment.

    0 讨论(0)
  • 2020-11-28 06:19

    Make an extension method that uses a couple of loops. I prefer this solution because it's readable (no linq), doesn't require System.Web.HttpUtility, and it handles duplicate keys.

    public static string ToQueryString(this NameValueCollection nvc)
    {
        if (nvc == null) return string.Empty;
    
        StringBuilder sb = new StringBuilder();
    
        foreach (string key in nvc.Keys)
        {
            if (string.IsNullOrWhiteSpace(key)) continue;
    
            string[] values = nvc.GetValues(key);
            if (values == null) continue;
    
            foreach (string value in values)
            {
                sb.Append(sb.Length == 0 ? "?" : "&");
                sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
            }
        }
    
        return sb.ToString();
    }
    

    Example

    var queryParams = new NameValueCollection()
    {
        { "order_id", "0000" },
        { "item_id", "1111" },
        { "item_id", "2222" },
        { null, "skip entry with null key" },
        { "needs escaping", "special chars ? = &" },
        { "skip entry with null value", null }
    };
    
    Console.WriteLine(queryParams.ToQueryString());
    

    Output

    ?order_id=0000&item_id=1111&item_id=2222&needs%20escaping=special%20chars%20%3F%20%3D%20%26
    
    0 讨论(0)
  • 2020-11-28 06:20

    I always use UriBuilder to convert an url with a querystring back to a valid and properly encoded url.

    var url = "http://my-link.com?foo=bar";
    
    var uriBuilder = new UriBuilder(url);
    var query = HttpUtility.ParseQueryString(uriBuilder.Query);
    query.Add("yep", "foo&bar");
    
    uriBuilder.Query = query.ToString();
    var result = uriBuilder.ToString();
    
    // http://my-link.com:80/?foo=bar&yep=foo%26bar
    
    0 讨论(0)
提交回复
热议问题