JArray的JObject tostring格式问题 [英] JObject tostring formatting issue for JArray

查看:528
本文介绍了JArray的JObject tostring格式问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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]
}

注意:

  • If you were serializing myObj directly you would be able to use a custom JsonConverter for the List<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-serialized JToken hierarchy, the serializer is not invoked and a custom converter for arrays will not be called.

演示小提琴此处.

这篇关于JArray的JObject tostring格式问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆