c# - 使用 Newtonsoft.Json 序列化时如何限制缩进深度
问题描述
使用 Newtonsoft.Json 序列化对象时,有没有办法在给定深度后停止序列化值的缩进?
例如,给定清单 1中的对象,有没有办法将JsonConverter
或JsonWriter
缩进到某个级别,以便在Dump 2或Dump 3中获得输出而不是Dump 1中的输出?
清单 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 ] } } ]
解决方案
是的,你可以通过继承这样的子类来限制缩进深度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
推荐阅读
- powershell - 将每行的字符串移动到特定位置
- java - 比较多个动态数组的每个元素
- swift - DatePickerDialog 仅显示最小日期
- python - 如何强制 xlwings 使用 COMRetryObjectWrapper 而不是 win32com api?
- python - 如何在定义自己的函数时迭代列表中的条目
- google-apps-script - 使用 Google 脚本从地址数据中获取地理位置数据
- firebase - 从登录用户创建的 Firebase 中读取数据 - Flutter
- python - 如何在小部件删除操作后使 Tkinter 小部件粘在窗口边框上?
- c# - Clipboard.SetContent 中的错误
- python - Gino + SQLAlchecmy + Postgres 如何reload模型?