JArray的JObject tostring格式问题 [英] JObject tostring formatting issue for JArray
问题描述
我对JObject有疑问,甚至是一个问题.这只是一个小例子,我有超过20个元素的大型列表,并且将它们保存为JSON格式,如果每个值都在换行符中,则读取起来确实很不好.有人可以向我解释如何解决此问题吗?
I have a question or rather an issue with the JObject. This is just a small example, I have large lists with more than 20 elements and I am saving these in JSON format and it is really bad to read if every value is in a new line. Can someone explain to me how to fix this?
代码:
var myObj = new
{
Vector = new List<int>{
1,2,3,4,5
}
};
Console.WriteLine(JToken.FromObject(myObj).ToString(Formatting.Indented));
输出是这样的:
{
"Vector": [
1,
2,
3,
4,
5
]
}
但是我希望它像这样:
{
"Vector": [1,2,3,4,5]
}
我已经尝试从MyObj
覆盖ToString()
,但是它也不起作用.
I already tried to override the ToString()
from MyObj
but it doesn't work either.
推荐答案
在写入JSON时,没有方法可以控制JToken
层次结构内特定嵌套标记的格式.因此,我们将需要自己滚动:
There is no method to control the formatting of specific nested tokens inside a JToken
hierarchy when writing to JSON. Thus we will need to roll our own:
public static partial class JsonExtensions
{
public static string ToFormattedString(this JToken token, params JsonConverter[] converters)
{
if (token == null)
throw new ArgumentNullException();
using (var sw = new StringWriter(CultureInfo.InvariantCulture))
{
using (var jw = new JsonTextWriter(sw) { Formatting = Formatting.Indented })
FormattedWriteTo(token, jw, 0, converters);
return sw.ToString();
}
}
static void FormattedWriteTo(JToken token, JsonTextWriter writer, int depth, params JsonConverter[] converters)
{
if (token == null)
{
writer.WriteNull();
}
else if (token is JObject obj)
{
IList<JToken> asList = obj;
writer.WriteStartObject();
for (int i = 0, n = asList.Count; i < n; i++)
FormattedWriteTo(asList[i], writer, depth+1, converters);
writer.WriteEndObject();
}
else if (token is JArray array)
{
// Disable formatting for arrays.
// You could smarten this up further by e.g. checking to see whether the array contents are all primitive JValue tokens.
var old = writer.Formatting;
// The question requires an extra space between the property name and the array value.
if (depth > 0 && old == Formatting.Indented)
writer.WriteWhitespace(" ");
writer.Formatting = Formatting.None;
writer.WriteStartArray();
for (int i = 0, n = array.Count; i < n; i++)
FormattedWriteTo(array[i], writer, depth+1, converters);
writer.WriteEndArray();
writer.Formatting = old;
}
else if (token is JProperty property)
{
writer.WritePropertyName(property.Name);
FormattedWriteTo(property.Value, writer, depth+1, converters);
}
else
{
// JValue, JRaw, JConstructor
token.WriteTo(writer);
}
}
}
然后JToken.FromObject(myObj).ToFormattedString()
根据需要生成:
{
"Vector": [1,2,3,4,5]
}
注意:
- 如果直接序列化
myObj
,则可以使用为List<int>
自定义JsonConverter
以禁用格式设置,如 如何仅将缩进序列化应用于某些属性? 和 Newtonsoft内联格式,用于在序列化时进行子元素 .但是因为您正在编写一个已经序列化的JToken
层次结构,所以不会调用序列化程序,也不会调用数组的自定义转换器.
- If you were serializing
myObj
directly you would be able to use a customJsonConverter
for theList<int>
to disable formatting, as shown in How to apply indenting serialization only to some properties? and Newtonsoft inline formatting for subelement while serializing. But because you are writing an already-serializedJToken
hierarchy, the serializer is not invoked and a custom converter for arrays will not be called.
演示小提琴此处.
这篇关于JArray的JObject tostring格式问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!