c# - 有没有办法在不改变格式的情况下修改 JSON?
问题描述
使用Newtonsoft.Json,您可以选择如何使用 .json 的Formatting
枚举和属性来格式化 JSON JsonTextWriter
。但是如果我从一个已经以某种方式格式化的 JSON 字符串开始并且我想修改它,有没有办法确保它保留它的格式?
我可以想到一些探索的途径:
- 当前是否有任何 JSON 库可以在不反序列化的情况下修改 JSON 字符串?
- 反序列化 JSON 字符串时,有没有办法检测字符串的格式,以便在重新序列化时可以应用相同的格式?
- 是否有一个函数将反序列化
JObject
与它来自的 JSON 字符串相结合,以便将对象的更改应用于旧字符串之上,而不是用于构建新字符串?
问题示例:
var obj = JObject.Parse(json);
obj["foo"] = "bar";
Console.WriteLine(obj.ToString(Formatting.Indented));
// {
// "baz": "qux",
// "foo": "bar"
// }
Console.WriteLine(obj.ToString(Formatting.None));
// {"baz":"qux","foo":"bar"}
// Not knowing how the input was formatted,
// how can I know what options to use?
解决方案可能是什么样的:
var format = JsonConvert.GetFormat(json); // No such method?
var obj = JObject.Parse(json);
obj["foo"] = "bar";
Console.WriteLine(obj.ToString(format));
(我知道有更多的方式来格式化 JSON,而不仅仅是选择Indented
or None
,但为了清楚起见,我让示例保持简单。)
解决方案
我会争辩说:这可能是徒劳的追求。
尽管它是人类可读的,但它很少被人类阅读。事实上,我更担心不小心将重要的东西解析进出有效对象。
但是,为了在 Newtonsoft 中获得一点乐趣,这适用于在原件缩进时没有缩进的格式。
var person = new Person()
{
Name = "John",
Colors = new List<string>() {"Red", "Blue","Green"}
};
var rawJson = Newtonsoft.Json.JsonConvert.SerializeObject(person, Formatting.Indented);
var newJson = Newtonsoft.Json.JsonConvert.SerializeObject(person, Formatting.None);
var settings = new Newtonsoft.Json.JsonSerializerSettings();
settings.Formatting = (Formatting)(newJson.Length <= rawJson.Length ? 1 : 0);
var finalJson = JsonConvert.SerializeObject(person, settings);
如果我们只关心 Newtonsoft,并且是否缩进,我相信这在以下前提下就足够了:
- 我们从客户端控制格式的变化
- 如果缩小,格式更改为 Newtonsoft 的默认值
- 假设它不能增长
- 如果转换使字符串保持相同的长度,则没有任何变化
当然,问题案例的出现如下:
- 收到的 JSON 包含额外的字符:
"First Name:"
,这在 Json 中有效,但在 Class 属性名称中无效,因此您可能需要担心一个属性。 - JSON 仍然是一个字符串,可能会出现各种奇怪的东西,因此以任何程度的确定性验证它都可能成为一场傻瓜比赛(建立一个更好的傻瓜)
事实上,如果某些工具的目的是将数据呈现给人类:选择最易读的格式(对我来说是缩进的)并始终显示它。
如果设计通常是机器,那么对于最小的有效载荷使用 none。我认为几乎所有习惯使用 JSON 的开发人员都希望将最小化的 JSON 作为有效负载。
推荐阅读
- reactjs - React Module build failed: SyntaxError: "..." is read-only
- powershell - 在 PowerShell 中发送带有 HTML 表格的电子邮件
- git - 新分支修复主分支中的问题后 Git Rebase 或 Merge
- gcc - 与开始/结束组链接:为什么我的链接会失败,除非某些库被留在组之外
- windows - 使用带有文件参数的 GetObject 会产生错误 432:自动化期间找不到文件名或类名
- rest - 如何在通过 REST API 更新文档时确保一致性
- excel - 如何使用 VBA 将 X 轴添加到已创建的折线图中?
- c# - 如何验证已使用 jquery 填充数据的下拉列表
- javascript - Angular4应用程序中的HTML转义拦截器
- android - 经典蓝牙发现没有提供除 MAC 地址以外的详细信息