【问题标题】:Format the nested property serialized json格式化嵌套属性序列化 json
【发布时间】:2017-03-23 14:16:50
【问题描述】:

我有一个 CSV 字符串,其中一个列值是 json 序列化的。

"Id,Name,Seo\r\n13,SpecialCollections,\"{\"\"SeoUrl\"\":\"\"special-collections\"\",\"\"SeoPageTitle\"\":null,\"\"SeoKeywords\"\":null,\"\"SeoDescription\"\":null}\"\r\n";

我正在使用JSON.NETServiceStack.Text 的组合从json-csv 序列化和反序列化我的数据,反之亦然。

所以,有了上面的CSVinput,我首先使用ServiceStack.Text辅助方法将其转换为.NET对象

var obj= csvInput.FromCsv<List<dynamic>>();

这给了我以Dictionary&lt;string,string&gt; 形式输出的每一行csv

1) {[Id, 13]} 
2) {[Name, SpecialCollections]}
3) {[Seo, {"SeoUrl":"special-collections","SeoPageTitle":null,"SeoKeywords":null,"SeoDescription":null}]}

然后我用 JSON.NET 辅助方法将上面的输出序列化并写入一个看起来像这样的文件

var serializedJson = JsonConvert
                .SerializeObject(obj, Formatting.Indented);

结果

[
  {
    "Id": "13",
    "Name": "SpecialCollections",
    "Seo": "{\"SeoUrl\":\"special-collections\",\"SeoPageTitle\":null,\"SeoKeywords\":null,\"SeoDescription\":null}"
  }
]

问题在于嵌套属性“Seo”,虽然它的值是序列化的 json,但这是因为它是 stringJSON.NET 被视为 string 并且不格式化。无论如何,我可以获得以下预期的结果?

预期结果:

[
  {
    "Id": "13",
    "Name": "SpecialCollections",
    "Seo":  {
        "SeoUrl": "special-collections",
        "SeoPageTitle": null,
        "SeoKeywords": null,
        "SeoDescription": null
      }
  }
]

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: json.net servicestack-text


    【解决方案1】:

    由于您的“Seo”值已经是一个 JSON 字符串,您需要将其反序列化为一个临时对象(例如 JObject),然后将其与其他键值对重新组合到一个新容器中并将其序列化为得到你想要的最终结果。这是一个简单的方法。

    首先,创建一个辅助方法,该方法可以确定字符串值是否为 JSON,并从中返回一个 JToken。

    public static JToken ToJToken(string s)
    {
        if (s == null)
            return JValue.CreateNull();
    
        // if the string is already JSON, parse it into a JObject (or JArray)
        if ((s.StartsWith("{") && s.EndsWith("}")) || (s.StartsWith("[") && s.EndsWith("]")))
            return JToken.Parse(s);
    
        // otherwise create a JValue from the non-JSON string
        return JToken.FromObject(s);
    }
    

    然后,使用上述辅助方法将您的 List&lt;Dictionary&lt;string, string&gt;&gt; 转换为 JArray,如下所示:

    JArray ja = new JArray(
        obj.Select(
            dict => new JObject(
                ((Dictionary<string, string>)dict).Select(
                    kvp => new JProperty(kvp.Key, ToJToken(kvp.Value))
                )
            )
        )
    );
    

    现在,要获取格式化的 JSON,您只需在 JArray 上调用 ToString()

    string json = ja.ToString();
    

    小提琴:https://dotnetfiddle.net/VDzGao

    【讨论】:

    • 我可以请你多一点帮助吗?如果源变为 List>,您将如何处理。我意识到,当我执行 FromCsv> 时,它会产生动态结果,但它是 List> 而不是 Dictionary 的形式,因为结果是 dynamic , 我认为创建 JObject 时 lamda 表达式不起作用。
    • 你是对的——我应该从你问题的 JSON 中的方括号中注意到这一点。我已经更新了我的答案和小提琴。
    • 至于动态,如果列表项实际上是 Dictionary 就像你说的,那么你应该可以转换 lambda 变量。
    • 如果您能检查这个更新的小提琴dotnetfiddle.net/Pfuc5w,我将不胜感激,我在创建令牌之前尝试将字符串转换为正确的类型。我只是想确定,如果我做对了,或者有更好的方法来做到这一点。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 2019-12-28
    • 2018-09-03
    相关资源
    最近更新 更多