我有一个CSV字符串,其中一个列的值是json序列化的。
"Id,Name,Seo\r\n13,SpecialCollections,\"{\"\"SeoUrl\"\":\"\"special-collections\"\",\"\"SeoPageTitle\"\":null,\"\"SeoKeywords\"\":null,\"\"SeoDescription\"\":null}\"\r\n";
我正在使用JSON.NET
和ServiceStack.Text
的组合来序列化和反序列化来自json-csv
的数据,反之亦然。
因此,使用上面的CSV
输入,我首先使用ServiceStack.Text帮助方法将其转换为.NET对象
var obj= csvInput.FromCsv<List<dynamic>>();
这为csv
的每一行提供了Dictionary<string,string>
形式的输出
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但是因为它是string
,JSON.NET
被视为string
并且没有格式化它。无论如何,我可以得到以下预期的结果吗?
预期结果:
[
{
"Id": "13",
"Name": "SpecialCollections",
"Seo": {
"SeoUrl": "special-collections",
"SeoPageTitle": null,
"SeoKeywords": null,
"SeoDescription": null
}
}
]
对此的任何帮助都将受到高度赞赏。
答案 0 :(得分: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<Dictionary<string, string>>
转换为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();