有没有办法用 DescriptorProto 反序列化未知对象?
Is there a way to deserialize an unknown object with a DescriptorProto?
我想找到一种使用 DescriptorProto 反序列化未知对象的方法。当我序列化一个 Person 时,这不是问题,因为我知道它的类型。但是当我反序列化时,我不知道我收到的对象类型,所以如何使用定义原型结构的 DescriptorProto,我可以创建一个像 ExpandObject 这样的对象?
这是我的 class :
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
基础 class 可用于反序列化任何任意负载,以及 Extensible
上的 static
方法比如Extensible.GetValue<int>(1)
。所以;这使您能够读取(或写入)任意有效负载。您可能需要创建一个 non-abstract class 来玩,但是 class Foo : Extensible {}
应该足够了,然后 Serializer.Deserialize<Foo>(source)
.
所以;第二部分是如何解析描述符。为此,请参阅 protobuf-net.Reflection
包。这包括您期望的常用描述符类型,包括 FileDescriptorSet
,因此:您可以使用 protobuf-net 的常规 Serializer.Deserialize<FileDescriptorSet>(source)
来获得 descriptor-set,您可以从中分离出来以通常的方式创建模型并发现属性,以与 Extensible
.
一起使用
我想找到一种使用 DescriptorProto 反序列化未知对象的方法。当我序列化一个 Person 时,这不是问题,因为我知道它的类型。但是当我反序列化时,我不知道我收到的对象类型,所以如何使用定义原型结构的 DescriptorProto,我可以创建一个像 ExpandObject 这样的对象?
这是我的 class :
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
基础 class 可用于反序列化任何任意负载,以及 Extensible
上的 static
方法比如Extensible.GetValue<int>(1)
。所以;这使您能够读取(或写入)任意有效负载。您可能需要创建一个 non-abstract class 来玩,但是 class Foo : Extensible {}
应该足够了,然后 Serializer.Deserialize<Foo>(source)
.
所以;第二部分是如何解析描述符。为此,请参阅 protobuf-net.Reflection
包。这包括您期望的常用描述符类型,包括 FileDescriptorSet
,因此:您可以使用 protobuf-net 的常规 Serializer.Deserialize<FileDescriptorSet>(source)
来获得 descriptor-set,您可以从中分离出来以通常的方式创建模型并发现属性,以与 Extensible
.