protobuf MessageToJson 删除值为 0 的字段

protobuf MessageToJson removes fields with value 0

我正在编写一个 Python 脚本来接收 protobuf,将它们转换为 json 对象,并将它们推送到另一个服务。我使用 json.loads(MessageToJson(protobuf)) 将 protobuf 转换为 python 字典对象。后来我用 json.dumps(dictionary).

将它转换回 json

我有一个带有可选枚举字段的原型,例如:

enum C_TYPE
{
    AB = 0;
    BC = 1;
    CD = 2;
}

当我收到一个字段指定为 BC 的原型时,一切都按我预期的那样工作。当我收到一个字段指定为 AB 的原型时,该字段将被忽略——它不会出现在 python 字典或随后的 json 转储中。我发现的一种解决方法是使用 json.loads(MessageToJson(protobuf, including_default_value_fields=True)) 但这将为所有缺失的字段创建默认值,而不仅仅是具有 0 枚举的字段。这意味着缺少带有枚举 0 的字段 - 但事实并非如此!

当设置为 0 时,获取枚举字段值的正确方法是什么?

没有正确的方法,我错误地定义了我的 protobufs。对于枚举字段,第一个值 默认值。这意味着如果一个 protobuf 没有设置值就通过了,它被设置为默认值,并且在转换为 json 时被忽略(除非你想保留所有默认值。)

因此,建议为默认值使用一次性名称,以便能够在设置时正确区分。即我应该将我的 protobuf 定义为:

enum C_TYPE
{
    NONE = 0;
    AB = 1;
    BC = 2;
    CD = 3;
}

来自Protobuf Documentation on Optional Fields And Default Values

For enums, the default value is the first value listed in the enum's type definition. This means care must be taken when adding a value to the beginning of an enum value list.

另外来自issue on golang/protobuf

This is working as intended. proto3 zero-values are omitted in the JSON format too. The zero-value should be a "throwaway" value: it's also what you will see if the sender of a serialized message sets the field to an invalid or unrecognized value.

在 C++ 的 protobuf 中,可以添加一个选项以始终打印原始字段。 在 MessageToJson 转换中添加此选项会使 protobuf 添加参数,即使它们被设置为零。

google::protobuf::util::JsonPrintOptions options;
options.always_print_primitive_fields = true;