【问题标题】:How do you limit indentation depth when serializing with Newtonsoft.Json使用 Newtonsoft.Json 序列化时如何限制缩进深度
【发布时间】:2021-01-04 03:59:36
【问题描述】:

使用 Newtonsoft.Json 序列化对象时,有没有办法在给定深度后停止序列化值的缩进?

例如,给定 清单 1 中的对象,有没有办法将 JsonConverterJsonWriter 子类化为仅缩进到某个级别,而不是 中的输出>Dump 1,你在 Dump 2Dump 3 中得到那个?

清单 1

var items = new[] {
    new { Name = "John",
          Age = 5,
          Address = new { Home = "No. 123, Oak Street", Email = "john@mail.com" },
          Extra = new { Serials = new[] { 20, 30, 40, 50 } }
    },
    new { Name = "Jean",
          Age = 2,
          Address = new { Home = "No. 321, Cliff Road", Email = "jean@mail.com" },
          Extra = new { Serials = new[] { 25, 35, 45, 55 } }
    }
};

转储 1:完全缩进

[ { “姓名”:“约翰”, “年龄”:5, “地址”: { “家”:“橡树街123号”, “电子邮件”:“john@mail.com” }, “额外的”: { “连续剧”:[ 20, 30, 40, 50 ] } }, { “姓名”:“让”, “年龄”:2, “地址”: { “家”:“悬崖路321号”, “电子邮件”:“jean@mail.com” }, “额外的”: { “连续剧”:[ 25, 35, 45, 55 ] } } ]

转储 2:深两层

[ { “姓名”:“约翰”, “年龄”:5, “地址”:{“家”:“橡树街 123 号”,“电子邮件”:“john@mail.com”}, “额外”:{“连续剧”:[20、30、40、50]} }, { “姓名”:“让”, “年龄”:2, “地址”:{“家”:“悬崖路321号”,“电子邮件”:“jean@mail.com”}, “额外”:{“连续剧”:[25、35、45、55]} } ]

转储 3:三层深度

[ { “姓名”:“约翰”, “年龄”:5, “地址”: { “家”:“橡树街123号”, “电子邮件”:“john@mail.com” }, “额外的”: { “连续剧”:[20、30、40、50] } }, { “姓名”:“让”, “年龄”:2, “地址”: { “家”:“悬崖路321号”, “电子邮件”:“jean@mail.com” }, “额外的”: { “连续剧”: [ 25, 35, 45, 55 ] } } ]

【问题讨论】:

  • 我会质疑你为什么需要这个,json 是一种可读的数据格式,而不是主要的显示工具。虽然要回答,但我不确定你如何在 Json.Net 或 Text.Json 中轻松实现这一点,我想你可以做一些后处理和解析缩进级别,并删除新的行和空格......虽然看起来很hacky跨度>
  • 这个问题能回答你的问题吗 - stackoverflow.com/questions/10453127/…
  • @Developer:不,它没有回答我的问题。我不是试图停止序列化超出一定深度。我想要的是在给定深度后停止缩进solution provided by Brian Rogers 满足我的需求。谢谢

标签: c# json .net json.net


【解决方案1】:

是的,您可以像这样子类化 JsonTextWriter 来限制缩进深度:

public class CustomIndentingJsonTextWriter : JsonTextWriter
{
    public int? MaxIndentDepth { get; set; } 

    public CustomIndentingJsonTextWriter(TextWriter writer) : base(writer)
    {
        Formatting = Formatting.Indented;
    }

    public override void WriteStartArray()
    {
        base.WriteStartArray();
        if (MaxIndentDepth.HasValue && Top > MaxIndentDepth.Value) 
            Formatting = Formatting.None;
    }

    public override void WriteStartObject()
    {
        base.WriteStartObject();
        if (MaxIndentDepth.HasValue && Top > MaxIndentDepth.Value) 
            Formatting = Formatting.None;
    }

    public override void WriteEndArray()
    {
        base.WriteEndArray();
        if (MaxIndentDepth.HasValue && Top <= MaxIndentDepth.Value) 
            Formatting = Formatting.Indented;
    }

    public override void WriteEndObject()
    {
        base.WriteEndObject();
        if (MaxIndentDepth.HasValue && Top <= MaxIndentDepth.Value) 
            Formatting = Formatting.Indented;
    }
}

您可以创建一个辅助方法以方便使用编写器:

public static string SerializeWithCustomIndenting(object obj, int? maxIdentDepth = null)
{
    using (StringWriter sw = new StringWriter())
    using (CustomIndentingJsonTextWriter jw = new CustomIndentingJsonTextWriter(sw))
    {
        jw.MaxIndentDepth = maxIdentDepth;
        JsonSerializer ser = new JsonSerializer();
        ser.Serialize(jw, obj);
        return sw.ToString();
    }
}

那么你可以这样做:

string json = SerializeWithCustomIndenting(yourObject, 2);  // indent to 2 levels max

这是一个工作演示:https://dotnetfiddle.net/XhwsGF

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 2023-03-18
    • 2021-09-21
    相关资源
    最近更新 更多