【问题标题】:Serialize string keys separated by dots with value to Json将由点分隔的字符串键序列化为 Json
【发布时间】:2017-10-11 22:10:47
【问题描述】:

我正在使用数据库来保存 Json 结构和值。使用 Testdata 结构作为字典看起来类似于:

Dictionary<string, string> input = new Dictionary<string, string>();
input.Add("application.shortName", "TestShortName");
input.Add("application.longName", "TestLongName");
input.Add("application.description", "TestDescription");
input.Add("application.deepNode.evenDeeperNode", "Values so deep, you can see Adelle rolling");
input.Add("common.yes", "YesTest");
input.Add("common.no", "NoTest");
input.Add("common.save", "SaveTest");
input.Add("common.pager.pagesLenghtBefore", "LengthTestDeepNode");

我从不知道来自数据库的名称,因此它可以是键的任何名称以及由点表示的任何深度,例如:“key1.key2.keyN”。 现在我想将从数据库中获得的每个键和值序列化为 Json。使用上面的 Testdata,它看起来像这样:

{
  "application": {
    "shortName": "TestShortName",
    "longName": "TestLongName",
    "description": "TestDescription",
    "deepNode": {
      "evenDeeperNode": "Values so deep, you can see Adelle rolling"
    },
    "common": {
      "yes": "YesTest",
      "no": "NoTest",
      "save": "SaveTest",
      "pager": {
        "pagesLengthBefore": "LengthTestDeepNode"
      }
    }
  }
}

我正在使用 JSON.NET,但我几乎没有触及表面,不知道是否有针对此的方法。我知道我可以将字典转换为 Json,但由于我的键的深度未知,这不可能直接实现。我试图想出一个循环来拆分键并将值添加到最后一个拆分的节点,尽管我从来没有真正编写过类似的程序。

我希望这似乎不是一个不恰当的问题,但我确实需要帮助。我很欣赏任何正确方向的提示。提前致谢

【问题讨论】:

  • 您是否尝试过使用 Dictionary 代替?这样,您可以嵌套 input["application"] = new Dictionary() 等,在对象图中更准确地表示 JSON 结构。
  • 这听起来像我想走的路。我读过类似的东西,但还没有找到解决方案。我会朝这个方向努力。

标签: c# json json.net


【解决方案1】:

您可以使用动态对象代替字典,例如:

var input = new {application = new {shortName = "TestShortName",
                                    longName = "TestLongName"
                                     ....},
                 common = new {yes = "YesTest",
                                  ..........}
                 }

或者使用ExpandoObject:

dynamic input = new System.Dynamic.ExpandoObject();
input.application = new System.Dynamic.ExpandoObject();
input.application.shortName = "TestShortName"
input.application.longName = "TestLongName"
.
.
.
input.application.deepNode.evenDeeperNode = "Values so deep, you can see Adelle rolling"

【讨论】:

  • 问题是我不知道来自数据库的名称。我得到一个像“key1.key2”这样的字符串。那我还能使用动态对象吗?我将编辑问题以进一步指出这一点
  • 好答案。我相信您也可以将 ExpandoObject 用作​​字典。
  • 好吧,再看看这个我发现你可以通过字符串名称将属性添加到 ExpandoObject。这是一个非常好的方法,我会用它来解决我的问题。谢谢!
  • @ame-no-kenshi 我知道这是个老问题了,请问你最后是怎么解决的?您能否根据您提供的示例给出您使用的代码示例?我有完全相同的问题。谢谢
  • @Dom 抱歉,我有一段时间没有活动了……我应该还有那个代码,并且会用我用来解决它的代码更新问题。
【解决方案2】:

如果您需要将字典转换为 json,那么下面的 sn-p 将为您完成:

        var input = new Dictionary<string, string>();
        input.Add("application.shortName", "TestShortName");
        input.Add("application.longName", "TestLongName");
        input.Add("application.description", "TestDescription");
        input.Add("application.deepNode.evenDeeperNode", "Values so deep, you can see Adelle rolling");
        input.Add("common.yes", "YesTest");
        input.Add("common.no", "NoTest");
        input.Add("common.save", "SaveTest");
        input.Add("common.pager.pagesLenghtBefore", "LengthTestDeepNode");

        var res = new Dictionary<string, Object>();
        foreach(var pair in input)
        {
            var key = pair.Key;
            var parts = key.Split('.');
            var currentObj = res;
            for (int i = 0; i < parts.Length-1; i++)
            {
                var property = parts[i];
                if (!currentObj.Keys.Contains(property))
                    currentObj[property] = new Dictionary<string, Object>();
                currentObj = (new Dictionary<string, Object>())currentObj[property];
            }

            currentObj[parts[parts.Length - 1]] = pair.Value;
        }

        var json = JsonConvert.SerializeObject(res, Formatting.Indented);

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多