使用protobuf-net时,空字符串反序列化为空字符串。

5
我正在使用protobuf-net来序列化和反序列化我的消息。我的消息还包含一些可能为空的字符串。然而,当我在另一端反序列化它们时,我得到了空字符串("")。
根据Google文档,字符串类型的默认值是空字符串。
这个问题的解决方案是什么?
以下是我使用的代码:
Command message = new Command();
message.s_value = null;
using (MemoryStream stream = new MemoryStream())
{
     Serializer.Serialize<Command>(stream, message);                
     stream.Close();
}

在反序列化相同的流时,我得到了s_value = ""

1个回答

5
我猜测你的类型在无参构造函数中将字符串显式设置为“”。你能检查一下吗? protobuf-net的处理方式是:
- 对于null,不发送任何内容(protobuf wire-format没有明确表示null的方法,但我们可以将其视为可选项并省略它) - 对于"",发送0长度的模式,应反序列化为"" - 对于非空字符串,发送长度和字符串,并进行反序列化
在反序列化期间,在null情况下,它只是保持字段/属性不变,因为它没有要处理的数据。如果类型将默认值设置为“”,则会保持为“”。
请注意,在“v2”版本中(我预计在未来两周内发布),您可以选择告诉它使用“不运行任何构造函数”的WCF方法,这将使其保持为null,即使默认构造函数分配了它。
还有一些技巧(在“v1”中)可以执行,以发送一个bool标志(作为单独的属性)表示null;如果您想要示例,请告诉我。
编辑:这里是一个“v1”技巧的示例,以解决此问题;“忽略构造函数”的“v2”方法可能是长期以来更好的选择。
[DataContract]
class Test {
    public Test() { Value = ""; } // a constructor that assigns the value

    [DataMember(Order = 1)]
    public string Value { get; set; } // our standard data
    [DataMember(Order = 2)]
    private bool ValueIsNull { // only exists to indicate explicit null
        get { return Value == null; }
        set { Value = value ? null : (Value ?? "");}
    }
}

1
我已更新问题并包含了我正在测试的示例代码。我检查了这段代码,发现字符串类型字段在声明时始终初始化为空字符串。我确实找到了一些解决方法(例如您在示例中提到的那个),但我想完成此操作而不包括更多信息或更改生成的代码。 - ata
@cornerback84 - 这段代码是从.proto生成的吗?还是你自己的生成器? - Marc Gravell
我使用了标志,但仍然产生相同的结果。我会进一步检查它。 - ata
@ata - 你有没有找到解决方案或解决此问题的方法? - Amrit Kr Lama
@AmritKrLama,11年后我不确定是否还记得,但我总算让它正常工作了。如果你仍然遇到问题,那么我知道至少Marc Gravel是C# protobuf编译器的作者(或参与者)。也许他可以帮助你找到前进的方向。 - ata
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接