【问题标题】:Serialize JSON in alphabetical order按字母顺序序列化 JSON
【发布时间】:2013-04-18 15:20:04
【问题描述】:

情况是这样,我首先从模型的每个类的对象中生成 2 个 JSON。一个 JSON 来自我当前的模型版本,另一个来自它的先前版本。 我的工作是比较每个 JSON 以找出 2 个模型之间的差异。

问题是,对象的属性没有以相同的顺序从一个 JSON 序列化到另一个 JSON。

有没有办法两个按字母顺序序列化具有所有属性的对象,以便我可以轻松地比较两个字符串?

谢谢!

【问题讨论】:

  • 你如何目前序列化?
  • 当你可以逐个属性比较而不用担心序列化结果的时候,为什么不在序列化之前做对象的比较呢?
  • 因为“旧模型”中的 JSON 存储在我查询的数据库中,所以我自己没有对象。我现在正在做的是检查“旧模型”的 JSON 中的所有属性是否仍然存在并且在“新模型”中相同对象的 JSON 中有效,这是一个回归测试。

标签: c# json string serialization deserialization


【解决方案1】:

如果您只想对 2 个 json 字符串进行一次比较,则网络上有此资源

http://tlrobinson.net/projects/javascript-fun/jsondiff

在 Json.Net 中,JToken 上有一个 DeepEquals 可用。

var json1 = JToken.Parse(jsonString1);
var json2 = JToken.Parse(jsonString2);
var jsonEqual = JToken.DeepEquals(json1, json2);

如果您想完全按照您的要求订购序列化,请参阅这篇文章。

https://stackoverflow.com/a/11309106/1181408

更新 - 显示订单序列化工作正常。

public class OrderedContractResolver : DefaultContractResolver
{
    protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(System.Type type, MemberSerialization memberSerialization)
    {
        return base.CreateProperties(type, memberSerialization).OrderBy(p => p.PropertyName).ToList();
    }
}

public class JsonSerializationTest1
{
    public string Test1 { get; set; }
    public string MyTest2 { get; set; }
    public string Test2 { get; set; }
    public string Test10 { get; set; }
}

public class JsonSerializationTest2
{
    public string Test10 { get; set; }
    public string Test1 { get; set; }
    public string MyTest2 { get; set; }
    public string Test2 { get; set; }
}

[TestMethod]
    public void TestJsonOrder()
    {
        var test1 = new JsonSerializationTest1 { Test1 = "abc", MyTest2 = "efg", Test10 = "hij", Test2 = "zyx" };
        var test2 = new JsonSerializationTest2 { Test1 = "abc", Test10 = "hij", Test2 = "zyx", MyTest2 = "efg" };

        var test1Json = JsonConvert.SerializeObject(test1);
        var test2Json = JsonConvert.SerializeObject(test2);

        Assert.AreNotEqual(test1Json, test2Json);

        var settings = new JsonSerializerSettings()
        {
            ContractResolver = new OrderedContractResolver()
        };

        var json1 = JsonConvert.SerializeObject(test1, Formatting.Indented, settings);
        var json2 = JsonConvert.SerializeObject(test2, Formatting.Indented, settings);

        Assert.AreEqual(json1, json2);

    }

【讨论】:

  • 什么似乎不起作用。我添加了一个快速示例,说明如何实现 OrderedContractResolver 然后序列化类。
  • DeepEquals 如果两个json中的元素顺序不同,则返回false
  • 我没有看过 Json.Net Deep Equal 代码,但这并不让我感到惊讶。
  • OrderedContractResolver 不适用于 json 的子元素。例如,另一个对象中的序列化对象的属性不会按字母顺序排列。
  • 是的。每个对象的属性都正确排序。现在它不会对项目集合进行排序,因为它不知道如何排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 2018-09-15
相关资源
最近更新 更多