繁体   English   中英

Protobuf-net序列化枚举值超出范围

[英]Protobuf-net serialize enum with value out of range

C#允许为枚举分配任何整数值。

当我尝试使用enum字段序列化(通过protobuf-net)对象时,该值超出范围,它会抛出异常:没有将wire-value映射到枚举PersonLevel。

我的枚举PersonLevel没有Flags属性。

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public enum PersonLevel
{
  Unknown = 1
}

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class Person
{
  ...

  public PersonLevel PersonLevel { get; set; }

  ...
}
var ms = new MemoryStream();

var person = new Person
{
  ...
  PersonLevel = (PersonLevel) 500
  ...
};

Serializer.Serialize(ms, person); //No wire-value is mapped to the enum PersonLevel

是否有任何设施可以在不改变业务对象的情况下(也许是任何protobuf attrubutes)?

有几种方法可以告诉它简化规则; 正如Ravadre所说, [Flags]自动禁用验证 - 它会导致EnumPassthru切换。 您也可以手动执行此操作 - 只要开始序列化/反序列化之前

RuntimeTypeModel.Default[typeof(PersonLevel)].EnumPassthru = true;

有描述:

/// <summary>
/// Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather
/// than enforcing .proto enum rules. This is useful *in particular* for [Flags] enums.
/// </summary>

你可以做的是创建一个int字段,你将打包到protobuf消息并公开一个Property,它将你的int字段暴露为你的类型的enum (作为一个包装器)。

如果你使用隐式字段,这可能会更难,因为protobuf可能会尝试序列化你的整数和你的enum属性。 您可以尝试明确[ProtoIgnore]您的enum属性。

但是,如果您的枚举标记有[Flags]属性,protobuf会自动为您执行此操作,因此将您的枚举更改为:

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
[Flags]
public enum PersonLevel
{
    Unknown = 1
}

应该让它发挥作用。 至少在第2版中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM