格式化嵌套 属性 序列化 json
Format the nested property serialized json
我有一个 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
视为a string
并且不格式化它。无论如何,我可以获得以下预期结果?
预期结果:
[
{
"Id": "13",
"Name": "SpecialCollections",
"Seo": {
"SeoUrl": "special-collections",
"SeoPageTitle": null,
"SeoKeywords": null,
"SeoDescription": null
}
}
]
如有任何帮助,我们将不胜感激。
由于您的 "Seo" 值已经是一个 JSON 字符串,您需要将它反序列化为一个临时对象(例如 JObject),然后将它与其他键值对重新组合到一个新容器中并对其进行序列化以获得您想要的最终结果。这是一个简单的方法。
首先,创建一个可以确定字符串值是否为 JSON 的辅助方法,并从中 return 一个 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();
Fiddle: https://dotnetfiddle.net/VDzGao
我有一个 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 辅助方法
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
视为a string
并且不格式化它。无论如何,我可以获得以下预期结果?
预期结果:
[
{
"Id": "13",
"Name": "SpecialCollections",
"Seo": {
"SeoUrl": "special-collections",
"SeoPageTitle": null,
"SeoKeywords": null,
"SeoDescription": null
}
}
]
如有任何帮助,我们将不胜感激。
由于您的 "Seo" 值已经是一个 JSON 字符串,您需要将它反序列化为一个临时对象(例如 JObject),然后将它与其他键值对重新组合到一个新容器中并对其进行序列化以获得您想要的最终结果。这是一个简单的方法。
首先,创建一个可以确定字符串值是否为 JSON 的辅助方法,并从中 return 一个 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();
Fiddle: https://dotnetfiddle.net/VDzGao