c# - Protobuf-net 枚举向后兼容性

标签 c# enums protocol-buffers protobuf-net backwards-compatibility

我试图在一个新的应用程序版本中为某个 protobuf 序列化的类添加一个新的枚举值,并且在测试时,注意到在给定这种新文件格式的情况下,以前的版本会抛出异常:

An unhandled exception of type 'ProtoBuf.ProtoException' occurred in protobuf-net.dll
Additional information: No {enum-type-name} enum is mapped to the wire-value 3

It is fairly obvious that it's telling me that there is no enum value for the int value of 3, but I always had the idea that Protocol Buffers defaulted to the zero-valued ("default") enum value (if such exists), in case that an actual enum value couldn't be mapped to.

To clarify, this can be reproduced using the following example (I am intentionally doing the deserialization step into a different class to mimic old app trying to load the new format):

// --- version 1 ---

public enum EnumV1
{
    Default = 0,
    One = 1,
    Two = 2
}

[ProtoContract]
public class ClassV1
{
    [ProtoMember(1)]
    public EnumV1 Value { get; set; }
}



// --- version 2 ---

public enum EnumV2
{
    Default = 0,
    One = 1,
    Two = 2,
    Three = 3 // <- newly added
}

[ProtoContract]
public class ClassV2
{
    [ProtoMember(1)]
    public EnumV2 Value { get; set; }
}

下面的代码会失败:

// serialize v2 using the new app
var v2 = new ClassV2() { Value = EnumV2.Three };
var v2data = Serialize(v2);

// try to deserialize this inside the old app to v1
var v1roundtrip = Deserialize<ClassV1>(v2data);

既然 v1 是公开的,在 v2 中序列化时是否可以使用一些元数据来避免这个问题?当然,我可以通过重写 v2 以使用单独的属性并保持枚举值不变来摆脱这个麻烦,但我希望尽可能使枚举向后兼容。

最佳答案

[ProtoContract(EnumPassthru=true)] 添加到您的枚举中将允许 protobuf-net 反序列化未知值。

不幸的是,没有办法追溯修复您的 v1。您将不得不使用不同的属性。

关于c# - Protobuf-net 枚举向后兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35600548/

相关文章:

c# - "Value can not be null"单例模式错误

c# - WebService 作为演示者

c - 如何将一个枚举的元素映射到另一个枚举的元素?

node.js - 您如何为用于 GRPC 的 protobuf 文件生成类型?

c# - 如何为 C# <proto/> 定义传递experimental_allow_proto3_optional 以在proto3 中启用optional?

c# - Rhino-Etl 和 MySQL 的问题

c# - 如何在 VB.NET 中编写 [DefaultValue(null)]? <DefaultValue(Nothing)> 不编译

c# - 如果枚举用作方法参数,是否始终需要在 C# 中进行强制转换?

Java Swagger UI - 如何正确配置枚举?

protocol-buffers - 如何将我自己的代码从 proto 文件添加到 JAVA 生成的类中?