使用ExpandoObject和IDictionary创建JSON时,允许同一键具有多个值

时间:2018-12-06 11:02:09

标签: c# json json.net expandoobject idictionary

我正在尝试使用ExpandoObject和IDictionary创建动态JSON。

在动态创建JSON期间,可能会重复出现Name或Value的实例。但是,将重复的Name或Value添加到ExpandoObject时,会出现错误:

  

具有相同键的项目已经添加。

下面是我的代码段:

DataTable dt_MappedColumns = (DataTable)ViewState["MappedColumns"];
dynamic ManCols = new ExpandoObject();
var dictionary1 = (IDictionary<string, object>)ManCols;
foreach (DataRow dr in dt_MappedColumns.Rows)
{
     dictionary1.Add(dr["TColumnName"].ToString(), dr["AColumnName"].ToString());
}
string Manjson = Newtonsoft.Json.JsonConvert.SerializeObject(dictionary1);

DataTable看起来像这样:

Sr.No TColumnName AColumnName
----- ----------- -----------
1     Apple       Lion
2     Orange      Tiger
3     Mango       Fox
4     Orange      Wolf

在上表中,前3行已成功添加到dictionary1中;但是,当我们尝试添加第四行时,会出现错误。

我想要的用于重复值的JSON结构如下所示:

  

{“ Apple”:“ Lion”,“ Orange”:[“ Tiger”,“ Wolf”],“ Mango”:“ Fox”}

是否可以从表中创建此JSON结构?

1 个答案:

答案 0 :(得分:2)

当然可以。在循环内部,您只需要检查关键字是否已存在于字典中并采取适当的措施即可。共有三种情况:

  • 该密钥不存在,因此请像现在一样添加它。
  • 该键存在,并且现有值是一个字符串,在这种情况下,您需要将其替换为包含旧字符串值和新字符串值的列表。
  • 该键存在,并且现有值是一个列表,在这种情况下,您只需要将新字符串添加到列表中即可。

代码如下:

foreach (DataRow dr in dt_MappedColumns.Rows)
{
    string key = dr["TColumnName"].ToString();
    string value = dr["AColumnName"].ToString();

    if (!dictionary1.ContainsKey(key))
    {
        // key does not already exist, so add it
        dictionary1.Add(key, value);
    }
    else
    {
        // key exists, get the existing value
        object existingValue = dictionary1[key];

        if (existingValue is string)
        {
            // replace the existing string value with a list
            dictionary1[key] = new List<string> { (string)existingValue, value }; 
        }
        else
        {
            // the existing value is a list, so add the new value to it
            ((List<string>)existingValue).Add(value);
        }
    }
}

提琴:https://dotnetfiddle.net/PERc0D