有没有一种简单的方法可以处理嵌套的Dictionary <string,object>类型,其中object是字符串还是另一个Dictionary <string,object>?

时间:2019-07-31 11:17:16

标签: c# dictionary object

我正在创建一个方法,该方法应该能够将Dictionary作为参数。

此方法准备一组要作为get / post参数附加到URI的参数。问题是,当我调用BuildQueryData(item)时,出现错误:无法将KeyValuePair转换为Dictionary。

    private string BuildQueryData(Dictionary<string, object> param)
    {
        if (param == null)
            return "";

        StringBuilder b = new StringBuilder();
        foreach (var item in param)
        {
            Dictionary<string, object> o;
            if (item.GetType() == "".GetType())
                b.Append(string.Format("&{0}={1}", item.Key, WebUtility.UrlEncode((string)item.Value)));
            else if (item.GetType() == new Dictionary<string, object>().GetType())
                b.Append(BuildQueryData(item));
        }


        try { return b.ToString().Substring(1); }
        catch (Exception e)
        {
            log.Error(e.Message);
            return e.Message;
        }
    }

根据在Dictionary中传递的对象的类型,它应该在传递字符串时创建一个字符串,或者在传递另一个Dictionary时自行调用。

提前感谢您的专业知识

2 个答案:

答案 0 :(得分:1)

您必须检查item.Value而不是item。 此外,我尝试通过使用is代替GetType()并在这里摆脱try-catch来改善您的代码。 (为什么还有Substring(1)?)
(以某种方式,我觉得建议的重载方法在这种情况下不太容易工作,但我对此不确定。)

private string BuildQueryData(Dictionary<string, object> param)
{
    if (param == null )
        return "";

    StringBuilder b = new StringBuilder();
    foreach (var item in param)
    {
        if (item.Value is string s)
            b.AppendFormat("&{0}={1}", item.Key, WebUtility.UrlEncode(s));
        else if (item.Value is Dictionary<string, object> dict)
            b.Append(BuildQueryData(dict));
    }

    return b.ToString();
}

答案 1 :(得分:1)

您可以通过创建一种使嵌套字典变平的方法来使其更加精美:

private static IEnumerable<KeyValuePair<string, string>>
    Flatten(Dictionary<string, object> dictionary)
{
    if (dictionary == null) yield break;
    foreach (var entry in dictionary)
    {
        if (entry.Value is string s)
        {
            yield return new KeyValuePair<string, string>(entry.Key, s);
        }
        else if (entry.Value is Dictionary<string, object> innerDictionary)
        {
            foreach (var innerEntry in Flatten(innerDictionary))
            {
                yield return innerEntry;
            }
        }
        else if (entry.Value == null)
        {
            // Do nothing
        }
        else
        {
            throw new ArgumentException(nameof(dictionary));
        }
    }
}

...然后像这样使用它:

string queryData = String.Join("&", Flatten(myNestedDictionary)
    .Select(e => e.Key + "=" + WebUtility.UrlEncode(e.Value)));