c# - 有没有办法用 DescriptorProto 反序列化未知对象?

标签 c# protocol-buffers protobuf-net

我想找到一种使用 DescriptorProto 反序列化未知对象的方法。当我序列化一个Person时,这不是问题,因为我知道它的类型。但是当我反序列化时,我不知道收到的对象类型,那么如何使用定义原型(prototype)结构的 DescriptorProto 创建一个像 ExpandObject 这样的对象呢?

这是我的课:

    class Person
    {
        [ProtoMember(1)]
        public int Id { get; set; }
        [ProtoMember(2)]
        public string Name { get; set; }
    }

我创建一个具有一些值的对象 Person,将其序列化并创建我的 .proto :

var person = new Person
{
   Id = 12345,
   Name = "Fred"
};
using (var file = File.Create(@"C:\temp\protobuf\person.bin"))
{
   Serializer.Serialize(file, person);
   file.SetLength(file.Position);
}
string proto = Serializer.GetProto<Person>();
File.WriteAllText(@"C:\temp\protobuf\person.proto", proto);

在我使用以下命令行创建 FileDescriptor 后:

protoc.exe person.proto --descriptor_set_out=person.pb

最后我想用 person.pb 的描述反序列化我的 person.bin ,如下所示:

byte[] payload = System.IO.File.ReadAllBytes(@"C:\temp\protobuf\person.pb");
FileDescriptorSet fileDescriptorSet = FileDescriptorSet.ParseFrom(payload);
FileDescriptorProto fileDescriptorProto = fileDescriptorSet.GetFile(0);
DescriptorProto requestDescriptor = fileDescriptorProto.GetMessageType(0);

/**
             requestDescriptor : 

            {name: "Person"
                field {
                  name: "Id"
                  number: 1
                  label: LABEL_OPTIONAL
                  type: TYPE_INT32
                  default_value: "0"
                }
                field {
                  name: "Name"
                  number: 2
                  label: LABEL_OPTIONAL
                  type: TYPE_STRING
                }
             }

             **/

object youhou;
using (var file = File.OpenRead(@"C:\temp\protobuf\person.bin"))
{
    //youhou = Serializer.Deserialize<Person>(file);
    // I don't know **Person** so i can't do this
}

起初,我想创建一个字符串、对象的字典而不是Person,但无法序列化它。

最佳答案

我是从protobuf-net(标签)的角度专门回答这个问题的;如果您使用 Google C# API,情况就会有所不同。

这里有一些不同的东西;然而,protobuf-net 目前没有 API 来加载专门带有描述符的东西!它确实有一个 Extensible可用于反序列化任何任意负载的基类,以及 static Extensible 上的方法如Extensible.GetValue<int>(1) 。所以;这使您能够读取(或写入)任意有效负载。您可能需要创建一个非抽象类来使用,但是 class Foo : Extensible {}应该足够了,那么Serializer.Deserialize<Foo>(source) .

所以;第二部分是如何解析描述符。为此,请参阅 protobuf-net.Reflection 包裹。这包括您期望的常见描述符类型,包括 FileDescriptorSet ,所以:你可以使用protobuf-net的常规Serializer.Deserialize<FileDescriptorSet>(source)获取描述符集,您可以用通常的方式从中分离模型并发现属性,以与 Extensible 一起使用.

关于c# - 有没有办法用 DescriptorProto 反序列化未知对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56143512/

相关文章:

c# - Protobuf-net序列化InvalidOperationException

c# - protobuf-net 版本 2.X 到 3.X 迁移

c# - 是否可以通过 COM 互操作转发委托(delegate)?

int - 如何在 protobuf 结构中使用整数?

protobuf-net - 列表的 Protobuf.net 对象图序列化

c++ - 从protobuf继承C++类

java - 在 apache flink 中反序列化 protobuf 事件中的事件时出现问题

c# - 无法打开主机 WCF REST 服务

c# - SQL 查询在 SSMS 中有效,但在 C# : SELECT denied 中无效

c# - Excel 2016 在保存错误时触发撤消?