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

发布于 2024-08-30 16:31:12 字数 430 浏览 6 评论 0原文

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

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

这是我正在使用的代码:

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

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

I am using protobuf-net to serialize and deserialize my messages. My message also contain come strings that can be null. However when I deserialize them on the other side, I get empty strings ("").

According to google docs, the default value for string type in empty string.
What could be the resolution for this issue?

Here is the code I am using:

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

Upon deserializing the same stream, I get s_value = ""

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿忘初心 2024-09-06 16:31:12

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

protobuf-net 处理此问题的方式是:

  • 对于 null,不发送任何内容(protobuf 有线格式无法显式表达 null code>,但我们可以将其视为可选并省略它)
  • ,应将其反序列化为 ""
  • 对于 "",发送 0 长度模式,对于 a 非空字符串、长度和字符串被发送,并被反序列化。

在反序列化期间,在 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 ?? "");}
    }
}

I would guess that your type is explicitly setting the string to "" in the parameterless constructor. Could you check?

The way that protobuf-net handles this is:

  • for a null, nothing is sent (the protobuf wire-format has no way of explicitly expressing a null, but we can treat it as optional and omit it)
  • for a "", a 0-length pattern is sent, which should be deserialized as ""
  • for a non-empty string, the length and the string is sent, and is deserialized

During deserialization, in the null case it simply leaves your field/property alone, since it has no data to process. If the type sets the default to "" it will stay as "".

Note that in "v2" (I expect to release this in the next two weeks), you can optionally tell it to use the WCF approach of "don't run any constructor", which will have the effect of leaving it as null even if the default constructor assigns it.

There are also some tricks you can do (with "v1") to send a bool flag (as a separate property) to mean null; let me know if you want an example of this.


Edit: here's an example of a "v1" trick to get around this; the "v2" approach of "ignore the constructor" is probably a better option long-term, though:

[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 ?? "");}
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文