我有一些标准对象,我使用protobuf进行序列化并存储在数据库中。是否可以将对象反序列化为通用标记(如json或xml),然后返回序列化的对象类型protobuf,而无需使用concreate实现该类?
[ProtoContract]
[Serializable]
internal class SomeDTO
{
/// <summary>
/// Gets or sets the Id.
/// </summary>
[ProtoMember(1)]
public string MyKey { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public int SomeId { get; set; }
[ProtoMember(4)]
public DateTime LastModifiedDate { get; set; }
}
此对象将序列化为:
{
"1": "asdklfhkajd",
"2": "Tim",
"3": 12345,
"4": "05/29/2015 5:50"
}
或者如果我的描述符过来但不是必需的:
{
"MyKey": "asdklfhkajd",
"Name": "Tim",
"SomeId": 12345,
"LastModifiedDate": "05/29/2015 5:50"
}
我当时正在看可能用ProtoReader编写东西?
编辑:我有一个读者可以工作:
private static JObject ProtoReaderDeserilizer(CollectionMetadata collectionMetadata, ProtoReader reader)
{
JObject obj = new JObject();
while (reader.ReadFieldHeader() > 0)
{
var field = collectionMetadata.FieldTypes[reader.FieldNumber].Field;
switch (reader.WireType)
{
case WireType.Variant:
obj[field] = reader.ReadInt64();
break;
case WireType.String:
obj[field] = reader.ReadString();
break;
case WireType.Fixed32:
obj[field] = reader.ReadSingle();
break;
case WireType.Fixed64:
obj[field] = reader.ReadDouble();
break;
case WireType.StartGroup:
// one of 2 sub-object formats
var tok = ProtoBuf.ProtoReader.StartSubItem(reader);
obj[field] = ProtoReaderDeserilizer(collectionMetadata, reader);
ProtoBuf.ProtoReader.EndSubItem(tok, reader);
break;
default:
reader.SkipField();
break;
}
}
return obj;
}
不,基本上。因为protobuf(二进制格式)是模棱两可的,并且没有关于如何解释字段(它是从类型和其他元数据获取的)的附加上下文,所以不可能可靠地反序列化数据。甚至像字符串和整数之类的简单事物也容易与多种类型混淆。同样,在protobuf级别上,没有日期/时间作为原语的概念。
明白我的意思:从上面的内容中获取二进制有效负载,然后将其丢到https://protogen.marcgravell.com/decode-由于存在多种可能性,它必须为您提供大多数类型的多种解释。它提供给您的选项集并不详尽。
您可以用SomeDTO
反序列化,然后使用您选择的任何JSON序列化器将其序列化为JSON,但是:您将需要具体的类型。我have考虑过添加选项以使用.proto模式和阅读器来执行此操作,但这并没有真正改变您所需要的-它只是改变了它的shape。
如果您知道布局但没有类型,则有are个选项,但此时仅创建类型就容易了。