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

ata*_*ata 3 protobuf-net

我正在使用 protobuf-net 来序列化和反序列化我的消息。我的消息还包含可以为空的字符串。但是,当我在另一侧反序列化它们时,我得到空字符串 ("")。

根据谷歌文档,空字符串中字符串类型的默认值。这个问题的解决方案是什么?

这是我正在使用的代码:

Command message = new Command();
message.s_value = null;
using (MemoryStream stream = new MemoryStream())
{
     Serializer.Serialize<Command>(stream, message);                
     stream.Close();
}
Run Code Online (Sandbox Code Playgroud)

反序列化同一个流后,我得到 s_value = ""

Mar*_*ell 5

你的类型在无参数构造函数中将字符串显式设置为“”。你能查一下吗?

protobuf-net 处理这个的方式是:

  • 对于 a null发送任何内容(protobuf 线格式无法明确表示 a null,但我们可以将其视为可选并省略它)
  • 对于 a "",发送一个长度为 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 ?? "");}
    }
}
Run Code Online (Sandbox Code Playgroud)