NameValueCollection to URL Query?

2020-01-27 12:37发布

I know i can do this

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

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

var newUrl = HttpUtility.Something("/page", nv);

12条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-01-27 13:24
string q = String.Join("&",
             nvc.AllKeys.Select(a => a + "=" + HttpUtility.UrlEncode(nvc[a])));
查看更多
Melony?
3楼-- · 2020-01-27 13:24

In AspNet Core 2.0 you can use QueryHelpers AddQueryString method.

查看更多
迷人小祖宗
4楼-- · 2020-01-27 13:25

This should work without too much code:

NameValueCollection nameValues = HttpUtility.ParseQueryString(String.Empty);
nameValues.Add(Request.QueryString);
// modify nameValues if desired
var newUrl = "/page?" + nameValues;

The idea is to use HttpUtility.ParseQueryString to generate an empty collection of type HttpValueCollection. This class is a subclass of NameValueCollection that is marked as internal so that your code cannot easily create an instance of it.

The nice thing about HttpValueCollection is that the ToString method takes care of the encoding for you. By leveraging the NameValueCollection.Add(NameValueCollection) method, you can add the existing query string parameters to your newly created object without having to first convert the Request.QueryString collection into a url-encoded string, then parsing it back into a collection.

This technique can be exposed as an extension method as well:

public static string ToQueryString(this NameValueCollection nameValueCollection)
{
    NameValueCollection httpValueCollection = HttpUtility.ParseQueryString(String.Empty);
    httpValueCollection.Add(nameValueCollection);
    return httpValueCollection.ToString();
}
查看更多
5楼-- · 2020-01-27 13:27

Would this work for you?

public static string BuildUrl(string relativeUrl, params string[] queryString)
{
    // build queryString from string parameters
    char[] trimChars = { ' ', '&', '?' };
    StringBuilder builder = new StringBuilder();
    string sepChar = "&";
    string sep = String.Empty;
    foreach (string q in queryString)
    {
        builder.Append(sep).Append(q.Trim(trimChars));
        sep = sepChar;
    }

    if (String.IsNullOrEmpty(builder.ToString())) { return relativeUrl; }
    else { return relativeUrl + "?" + builder.ToString(); }
}

Use:

string url = BuildUrl("/mypage.apsx", "qs1=a", "qs2=b", "qs3=c");
查看更多
倾城 Initia
6楼-- · 2020-01-27 13:32

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
查看更多
地球回转人心会变
7楼-- · 2020-01-27 13:32

You can use.

var ur = new Uri("/page",UriKind.Relative);

if this nv is of type string you can append to the uri first parameter. Like

var ur2 = new Uri("/page?"+nv.ToString(),UriKind.Relative);
查看更多
登录 后发表回答