【问题标题】:Allow multiple values for the same key when creating JSON using ExpandoObject and IDictionary使用 ExpandoObject 和 IDictionary 创建 JSON 时,允许同一键有多个值
【发布时间】:2018-12-07 05:42:23
【问题描述】:

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

在动态创建 JSON 期间,可能会出现名称或值重复的情况。但是,将重复的名称或值添加到 ExpandoObject 时,会出现错误:

已添加具有相同密钥的项目。

下面是我的代码 sn-p :

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 结构如下所示:

{“苹果”:“狮子”,“橙色”:[“老虎”,“狼”],“芒果”:“狐狸”}

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

【问题讨论】:

  • 与其只提供一个包含我们不知道的数据的代码 sn-p,不如创建一个我们可以运行的 minimal reproducible example 更有用,它包括所有数据需要重现问题 - 理想情况下还需要解释您希望输出的内容。
  • @JonSkeet :编辑,如果有帮助的话..
  • 不是很多 - 我仍然无法复制/粘贴/编译/运行该代码。 (您的问题实际上是否依赖于它在 DataTable 中的开始?我不明白为什么应该这样做。)但从根本上说,您想要的 JSON 是一个糟糕的 JSON,具有明确的不确定结果 - 请参阅 tools.ietf.org/html/rfc7159#section-4。跨度>
  • @JonSkeet:JSON 结构编辑
  • 澄清 JonSkeet 的评论:创建一个 有时 有一个列表但其他时候只有一个值的 json 是个坏主意。这对接收该 json 的人来说是一个严重的负担。正确的解决方案是总是为任何允许多个副本的属性创建一个列表。在这里,“Orange”允许有重复项,所以总是把它列成一个列表。一个值:{"Orange": ["Tiger"]}。如果允许 any 键有重复项,则将它们全部列出。在这种情况下,输出将是{"Apple": ["Lion"], "Orange": ["Tiger", "Wolf"], "Mango": ["Fox"]}。更容易处理。

标签: c# json json.net expandoobject idictionary


【解决方案1】:

当然可以。在您的循环中,您只需要检查字典中是否已存在密钥并采取适当的措施。分三种情况:

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

代码如下:

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

【讨论】:

  • Just Awsome .... 像魅力一样工作 :) 感谢@BrainRogers 提供的宝贵帮助。运行上述代码后,我得到了带有转义字符的 Json 字符串,因为我使用的是 Visual Studio。 .. "{\"Apple\":\"Lion\",\"Orange\":[\"Tiger\",\"Wolf\"],\"Mango\":\"Fox\"}" 如何我们可以从 Json 字符串中删除 Escape '\' 字符吗..
  • @Mufaddal 如果您在 JSON 中获得转义字符,您可能正在对数据进行双重序列化。当您使用 JsonConvert.SerializeObject() 序列化数据并且您还使用框架方法(如 ASP.NET MVC 中的 Json())返回数据时,就会发生这种情况。有关示例以及如何修复它,请参见 Invalid format with Json when converting DataTable with Json.Net
  • 感谢您的回复,但是我通过将其转换为 JObject 然后按如下方式使用它解决了这个问题: var Varjson = JObject.Parse(Manjson);然后使用 Varjson 对象。 :) 干杯。
猜你喜欢
  • 2017-03-21
  • 2010-12-27
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 2015-12-21
  • 2019-08-21
  • 2016-04-23
相关资源
最近更新 更多