最稳妥的JSON字符串缩进方案是使用System.Text.Json的JsonSerializerOptions并设置WriteIndented = true,它内置支持、轻量安全,.NET Core 3.0+默认推荐;该选项仅影响序列化输出(4空格缩进),不改变反序列化行为,且不可配置缩进宽度。
JSON字符串缩进用JsonSerializerOptions最稳妥
直接用system.text.json内置的序列化器,比手动拼接或第三方库更轻、更安全,也避免了newtonsoft.json(json.net)的额外依赖。.net core 3.0+ 默认推荐这条路。
关键不是“怎么加空格”,而是“怎么让序列化器自动做这件事”——靠JsonSerializerOptions里的WriteIndented开关:
-
WriteIndented = true:开启缩进,输出带换行和4空格缩进的可读JSON -
WriteIndented = false(默认):紧凑格式,无换行无空格 - 该选项只影响序列化(对象→字符串),不改变反序列化行为
示例:
var options = new JsonSerializerOptions { WriteIndented = true };
string json = JsonSerializer.Serialize(new { Name = "Alice", Age = 30 }, options);
// 输出:
// {
// "Name": "Alice",
// "Age": 30
// }
别用JsonConvert.SerializeObject(Newtonsoft)除非已有依赖
如果你项目里已经用了Newtonsoft.Json,那确实可以继续用JsonConvert.SerializeObject配合Formatting.Indented——但它不是.NET原生方案,且在高频/低延迟场景下有轻微性能开销。
常见踩坑点:
- 忘记传
Formatting.Indented参数,结果还是压缩格式:JsonConvert.SerializeObject(obj)→ ❌;JsonConvert.SerializeObject(obj, Formatting.Indented)→ ✅ - 混用两个JSON库导致类型解析冲突,比如
JObject和JsonElement不能直接互转 - .NET 6+ 新项目硬上
Newtonsoft,反而增加维护成本和冷启动时间
原始JSON字符串想美化?必须先解析再重序列化
如果手头只有string类型的JSON(比如从API响应拿到的紧凑字符串),不能直接“加缩进”。它本质是文本,没有结构信息——你得先解析成对象,再用带缩进的选项重新序列化。
否则会出错或白忙活:
- 错误做法:对字符串做正则替换加空格 → 容易破坏引号内内容、转义字符、注释(虽然JSON本不该有注释)
- 正确路径:
JsonSerializer.Deserialize<jsonelement>(rawJson)</jsonelement>→ 再Serialize(..., options) - 注意:若原始JSON非法(如末尾逗号、单引号),解析阶段就会抛
JsonException,这是必要校验,不是bug
简写示例:
string raw = @"{""name"":""Bob"",""tags"":[""a"",""b""]}";
var doc = JsonSerializer.Deserialize<JsonElement>(raw);
string pretty = JsonSerializer.Serialize(doc, new JsonSerializerOptions { WriteIndented = true });
缩进宽度不可配置,4空格是硬编码值
System.Text.Json目前(.NET 8)不支持自定义缩进空格数,WriteIndented = true固定输出4个空格。这不是bug,是设计选择。
如果你真需要2空格或tab,只能:
- 用
Newtonsoft.Json的JsonTextWriter.Indentation和IndentChar控制(但代价是引入旧库) - 或解析后手动替换前导空格(不推荐:易误伤字符串字面量中的空格)
- 或封装一层包装器,在
Serialize后对每行开头的4空格做二次处理(仅限极端需求)
绝大多数调试、日志、配置导出场景,4空格完全够用;纠结这个宽度,往往说明还没遇到真正难搞的问题。


















