1

我正在使用 Windows 平台上的 protobuf-net v3.0.101 并在使用 grpc protobuf-net 对其进行序列化时获取以下字符串数组中的空值异常:

我已经这样定义了我的 DataContract:

[DataContract]
public class StringArray
{
    [DataMember(Order = 1)]
    public string[] StrArray;
}

这是我尝试序列化的实际消息:

var stringArray = new StringArray() { StrArray = new string[] { "1", "2", null, "3" } };

而且,这就是我调用 Serializer 的方式:

method.RequestMarshaller.ContextualSerializer(request, transmitPayload);

这是一个例外:

FAIL: Error: Unhandled exception in required test method. An element of type System.String was null; this might be as contents in a list/array. (System.NullReferenceException: An element of type System.String was null; this might be as contents in a list/array
   at ProtoBuf.Internal.ThrowHelper.ThrowNullRepeatedContents[T]()
   at ProtoBuf.Serializers.RepeatedSerializer`2.Write[TEnumerator](State& state, Int32 fieldNumber, SerializerFeatures category, WireType wireType, TEnumerator& values, ISerializer`1 serializer)
   at ProtoBuf.Serializers.VectorSerializer`1.Write(State& state, Int32 fieldNumber, SerializerFeatures category, WireType wireType, T[] values, ISerializer`1 serializer)
   at ProtoBuf.Serializers.RepeatedSerializer`2.WriteRepeated(State& state, Int32 fieldNumber, SerializerFeatures features, TCollection values, ISerializer`1 serializer)
   at proto_29(State& , StringArray )
   at ProtoBuf.ProtoWriter.State.SerializeRoot[T](T value, ISerializer`1 serializer)
   at ProtoBuf.MeasureState`1..ctor(TypeModel model, T& value, Object userState, Int64 abortAfter)
   at ProtoBuf.Meta.TypeModel.Measure[T](T value, Object userState, Int64 abortAfter)
   at ProtoBuf.Meta.TypeModel.ProtoBuf.IMeasuredProtoOutput<System.Buffers.IBufferWriter<System.Byte>>.Measure[T](T value, Object userState)
   at ProtoBuf.Grpc.Configuration.ProtoBufMarshallerFactory.ContextualSerialize[T](T value, SerializationContext context)
4

1 回答 1

1

这里的问题是:底层 protobuf 格式没有 null 的概念。我根本无法以明显的方式将其编码到数组中。

在 V2 中,我们做了一些事情,将所有数组元素(启用此功能)包装在一个额外的层中,以允许我们解释空值,但这会占用更多的在线空间,不是就地静默替换,并且不是t 显而易见的解释。我还没有在 V3 中重新添加它,但是如果非常需要它,我们可以这样做。然而,今天这样做的一种懒惰方法是序列化Foo[]whereFoo是一个类型,它具有作为string唯一成员的字段 1。它可能是一个值类型 - 甚至可能是readonly struct record具有单个字段的 a。

于 2021-12-18T13:57:17.283 回答