将Dictionary转换为url参数字符串?

时间:2014-05-07 13:18:36

标签: c# asp.net-mvc dictionary webforms

有没有办法将代码中的Dictionary转换为url参数字符串?

e.g。

// An example list of parameters
Dictionary<string, object> parameters ...;
foreach (Item in List)
{
    parameters.Add(Item.Name, Item.Value);
}

string url = "http://www.somesite.com?" + parameters.XX.ToString();

在MVC HtmlHelpers内部,您可以使用UrlHelper(或控制器中的Url)生成URL,但在Web窗体代码隐藏中,此HtmlHelper不可用。

string url = UrlHelper.GenerateUrl("Default", "Action", "Controller", 
    new RouteValueDictionary(parameters), htmlHelper.RouteCollection , 
    htmlHelper.ViewContext.RequestContext, true);

如果没有MVC助手,如何在C#Web窗体代码隐藏(在MVC / Web窗体应用程序中)中完成?

12 个答案:

答案 0 :(得分:45)

一种方法是:

var url = HttpUtility.UrlEncode(
    string.Format("http://www.yoursite.com?{0}",
        string.Join("&",
            parameters.Select(kvp =>
                string.Format("{0}={1}", kvp.Key, kvp.Value)))));

如果你不需要它,你可以摆脱UrlEncode,我只是为了完整而添加它。

答案 1 :(得分:10)

创建一个静态助手类:

public static string QueryString(IDictionary<string, object> dict)
{
    var list = new List<string>();
    foreach(var item in dict)
    {
        list.Add(item.Key + "=" + item.Value);
    }
    return string.Join("&", list);
}

答案 2 :(得分:5)

最简短的方法:

string s = string.Join("&", dd.Select((x) => x.Key + "=" + x.Value.ToString()));

但更短并不意味着更高的效率。更好地使用StringBuilderAppend方法:

first = true;
foreach(var item in dd)
{
    if (first)
        first = false;
    else
        sb.Append('&');
    sb.Append(item.Key);
    sb.Append('=');
    sb.Append(item.Value.ToString());
}

答案 3 :(得分:4)

您可以使用IEnumerable<string>String.Join

var parameters = new List<string>();
foreach (var item in List)
{
    parameters.Add(item.Name + "=" + item.Value.ToString());
}

string url = "http://www.somesite.com?" + String.Join("&", parameters);

或更短

string baseUri = "http://www.somesite.com?";
string url = baseUri + String.Join("&", list.Select(i => $"{i.Name}={i.Value}"));

答案 4 :(得分:2)

这是您要找的(未经测试的代码)吗?

StringBuilder sb = new StringBuilder();
sb.Append("http://www.somesite.com?");

foreach(var item in parameters)
{
sb.append(string.Format("{0}={1}&", item.Key, item.Value))
}
string finalUrl = sb.ToString();
finalUrl = finalUrl.Remove(finalUrl.LasIndexOf("&"));

答案 5 :(得分:2)

你可以试试这个:

var parameters = new Dictionary<string, string>(); // You pass this
var url = "http://www.somesite.com?";
int i = 0;
foreach (var item in parameters)
{
    url += item.Key + "=" + item.Value;
    url += i != parameters.Count ? "&" : string.Empty;
    i++;
}

return url;

我没有运行逻辑,但这可能对你有帮助。

如果你将成为网络形式的UrlRouting,那么这将是一个不同的故事。

退房:

http://msdn.microsoft.com/en-us/library/cc668201(v=vs.90).aspx

答案 6 :(得分:2)

我已经编写了这些扩展方法:

将查询字符串添加到基本网址:

public static string AddQueryString(this string url, IDictionary<string, object> parameters) => 
     $"{url}?{parameters.ToQueryString()}";

将参数字典转换为查询字符串:

private static string ToQueryString(this IDictionary<string, object> parameters) => 
    string.Join("&", parameters.Select(x => $"{x.Key}={x.Value}"));

要转换为查询字符串的实际代码:

string.Join("&", parameters.Select(x => $"{x.Key}={x.Value}"));

编辑:

在生产中使用时,请考虑在此函数中使用URL.Encode对参数进行编码。如果使用此功能,请确保字典中的参数尚未编码。

答案 7 :(得分:1)

您可以使用Microsoft.AspNetCore.WebUtilities:

中的QueryHelpers
import os
os.environ['BRIGHTWAY2_DIR']='path/to/my/other/dir'
from brightway2 import *

答案 8 :(得分:1)

<块引用>
// this is wrong
var url = string.Format("http://www.yoursite.com?{0}",
    HttpUtility.UrlEncode(string.Join("&",
        parameters.Select(kvp =>
            string.Format("{0}={1}", kvp.Key, kvp.Value))))); 

我从(迈克的)接受的答案中尝试了这段代码,但没有奏效。其实这是错误的。让我们看看这个答案有什么问题。 如果您编写 HttpUtility.UrlEncode("a=1&b=2"),它也会对 =& 进行编码并返回不正确的 "a%3d1%26b%3d2"。因此,您只需要像这样对键和值进行编码:

// this works
var encodedUrl = string.Format("http://www.yoursite.com?{0}", 
    string.Join("&", parameters.Select(kvp => string.Format("{0}={1}", 
        HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value)))));

或(使用字符串插值)

var encodedUrl = $"http://www.yoursite.com?{string.Join("&", parameters.Select(kvp => $"{HttpUtility.UrlEncode(kvp.Key)}={HttpUtility.UrlEncode(kvp.Value)}"))}";

答案 9 :(得分:0)

您可以将以下类添加到项目中并使用扩展方法。

using System.Collections.Generic;
using System.Linq;
using System.Text;

public static class CollectionExtensions {
    public static string ToQueryString(this IDictionary<string, string> dict)
    {

    if (dict.Count == 0) return string.Empty;

    var buffer = new StringBuilder();
    int count = 0;
    bool end = false;

    foreach (var key in dict.Keys)
    {
        if (count == dict.Count - 1) end = true;

        if (end)
            buffer.AppendFormat("{0}={1}", key, dict[key]);
        else
            buffer.AppendFormat("{0}={1}&", key, dict[key]);

        count++;
    }

    return buffer.ToString();
}
}

使用代码:

var queryString = dictionary.ToQueryString();

答案 10 :(得分:0)

我并不是说这个选项更好(我个人认为不是),但是我在这里只是说它存在。

QueryBuilder类:

var queryStringDictionary = new Dictionary<string, string>
{
    { "username", "foo" },
    { "password", "bar" }
};

var queryBuilder = new QueryBuilder(queryStringDictionary);
queryBuilder.Add("type", "user");

//?username=foo&password=bar&type=user
QueryString result = queryBuilder.ToQueryString();

答案 11 :(得分:0)

使用 Newtonsoft JSON,您可以通过创建扩展函数将匿名对象快速序列化为 http 查询。

此方法还支持使用方括号将数组作为参数传递给 PHP。

    public static string Join(this List<string> a, string seperator)
    {
        return string.Join(seperator, a.ToArray());
    }

    public static string ToHttpQuery(this object a)
    {
        string result = "";

        foreach (var b in JObject.FromObject(a))
        {
            if (result.Length > 0)
                result += "&";

            if (b.Value.Type == JTokenType.Array)
                result += b.Value.Select(x => b.Key + "[]=" + Uri.EscapeDataString(x.ToString())).ToList().Join("&");
            else
                result += b.Key + "=" + Uri.EscapeDataString(b.Value.ToString());
        }

        return result;
    }

示例用法:

        string query = new
        {
            test = new string[] { "ree", "roo" },
            myId = 123,
            port = PORTS.MAIN_INTERFACE_IO,
            targetUrl = "http://example.com/?fee=123"
        }.ToHttpQuery();
        
        string myUrl = "http://example.com/?" + query;