C#/Python Json序列化时控制字段顺序

小柊 发表于 2018年08月13日 22时39分49秒

一、背景

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

 

Json广泛的用于数据传输的时候(比如Web的前后端数据传输),对于这种场景我们不会刻意的去控制对象序列化后,Json字符串中的字段顺序。因为在这种场景下,我们的要求只是能用就好。但一些特殊的情况,例如需要对一个对象进行Json序列化,并对产生的Json字符串进行RSA签名,那就一定要控制Json字符串中的字段顺序了。因为如果不严格的控制字段顺序,明明是一样的对象会因为序列化后Json字符串中的字段顺序不一致,导致产生的签名结果不一致。

那么,在C#和Python里,有什么方法可以控制对象字段在Json序列化时的顺序呢?

 

注:

后面的实现中,为了保证展示的效果,将使用以下测试数据:

用户(User)字段:

字段名 字段类型(C#/Python)
Uid int/int 100000
Username string/str hiiragi
Password string/str 0123456789abcdef0123456789abcdef
Phone string/str 13412341234
Enable bool/bool true

 

要求输出的Json字符串中,所有的字段以字段名升序排序。

 

二、Python 下的实现

这次我们先讲一下Python下的实现,因为比较简单。

Python下,我们常常会把需要序列化的数据存到一个字典(dict)对象中,但在Python中,字典对象是利用散列表实现的,这就导致了默认的字典对象是无序的。也就是说,您存入字典的键值对顺序可能会因为Python自动扩容字典时的重新哈希而被破坏。

例如下面的代码:

 

上面的代码笔者在运行完后输出字典对象d,解释器的输出结果是这样的:

 

很明显,这个顺序不是我当时存入时使用的顺序。

 

为了解决这个问题,Python提供了一个叫做OrderedDict的字典变种,它能够在添加键时保持顺序,所以在每一次对键进行迭代的时候都能保证顺序是一定的。

现在,我们就以第一章中的测试数据为例,进行一个简单的演示: