【发布时间】:2022-01-03 10:25:54
【问题描述】:
如果您在子线程中对正在序列化的对象调用.GetProperty 方法,JsonConvert.SerializeObject 会更改 JSON 中字段的排序顺序。
class Program
{
static void Main(string[] args)
{
var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
var task = Task.Factory.StartNew(() =>
{
var token = CreateRandomToken();
_ = typeof(TestObject).GetProperty("Version");
var str = JsonConvert.SerializeObject(token);
Console.WriteLine(str);
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
Console.ReadLine();
}
private static TestObject CreateRandomToken()
=> new TestObject { TokenHash = "123456789", Name = "Name", Version = "123" };
}
public class TestObject
{
public string TokenHash { get; set; }
public string Name { get; set; }
public string Version { get; set; }
}
Version 字段位于 JSON 的开头,而不是结尾
如果我们删除
_ = typeof(TestObject).GetProperty("Version");
- 那么字段的排序不会改变 或者如果你在主线程中调用代码,那么排序也不会改变
如果我用属性[JsonProperty (Order = 1)] 装饰我的对象,那么排序将与我在属性中指示的不同
我该如何解决?修复不使用 attr [JsonProperty (Order = 1)]
更新: 我们使用 JSON 字符串生成数字签名,如果字段顺序发生更改,数字签名将无效,因此字段顺序对我来说很重要
【问题讨论】:
-
使用属性是你修复它的方法。为什么会出现这个问题?
-
我不想将属性挂在所有类上,因为这些类有很多,而且它们都可能用于序列化为 JSON
-
我会考虑实施
DefaultContractResolver或继续使用JsonProperty。除非您指定,否则属性不会保持其顺序。他们为什么要默认保持订单? -
我的意思是为什么订单有问题?
-
我相信对根 JSON 对象使用
JObject.Parse或类似内容会保持在 JSON 中找到的顺序。然后,您可以手动操作对象层次结构,而不是序列化/反序列化。