如何使用 protobuf-net 反序列化 .asmx webservice 中指定的对象

Posted

技术标签:

【中文标题】如何使用 protobuf-net 反序列化 .asmx webservice 中指定的对象【英文标题】:How do I deserialize objects specified in a .asmx webservice using protobuf-net 【发布时间】:2012-02-07 15:04:23 【问题描述】:

如何在 WebReference 的类中指定 ProtoBuf-Net 属性?

我有一个 .net 2.0 Web 服务,我在其中使用 protobuf 创建一个 byte[]。 在我的客户端(v3.5)中,我想将 byte[] 反序列化到相应的类中。 但是,当我反序列化时,我得到的只是 0 和空值。

这样做的原因是我将类型指定为 Web Reference 类。

不能正常工作

using (MemoryStream stream = new MemoryStream(byteArray))

            List<WebReferencePerson> personsList =  Serializer.DeserializeWithLengthPrefix<List<WebReferencePerson>>(stream, PrefixStyle.Base128);
            stream.Close();

但是,如果我在客户端中创建另一个类 Person1 并指定 Proto 属性 [ProtoContract] 和 [ProtoMember()],我会得到正确的反序列化数据。 即

[ProtoContract]
class Person1

    [ProtoMember(1)]
    string Name get;set;
    [ProtoMember(2)]
    int Id get;set;

这很好用。

List<Person1> personsList = 
Serializer.DeserializeWithLengthPrefix<List<Person1>>(stream, PrefixStyle.Base128);

有没有办法使用 Web Reference 中的类来反序列化数据? 如何为 Web Reference 类指定 Protobuf 属性? 或者 我是否必须使用 Proto 属性指定不同的类才能反序列化来自 WebService 的数据?

【问题讨论】:

【参考方案1】:

asmx 生成的类型不会有 tag-markers 标记;有很多方法可以解决这个问题:

反序列化到 protobuf DTO 使用部分类来告诉它布局 在代码中定义布局

第二个选项看起来像:

namespace Your.Namespace 
    [ProtoContract]
    [ProtoPartialMember(1, "Name")]
    [ProtoPartialMember(2,  "Id")]
    partial class WebReferencePerson 

第三个选项是,作为 app-start 的一部分:

RuntimeTypeModel.Default.Add(typeof(WebReferencePerson), false)
                    .Add("Name", "Id");

使用这两种方法中的任何一种,它都应该反序列化。

【讨论】:

谢谢马克。尝试了第二种方法,它的工作原理。不完全确定您所说的第一种方法是什么意思(是否与我在最初的帖子中通过创建一个单独的类并分配 protobuf-net 属性所解释的一样?)我猜第三种方法仅适用于 v2 并且我目前正在工作在 v1 上。 是的,第一种方法就是您所描述的,是的,第三种方法仅适用于 v2。

以上是关于如何使用 protobuf-net 反序列化 .asmx webservice 中指定的对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 protobuf-net 序列化/反序列化锯齿状/嵌套数组?

C# Protobuf-net:如何从网络流中连续反序列化?

使用知道架构的 protobuf-net 反序列化未知对象

Protobuf-Net 总是反序列化一个空列表

使用 protobuf-net 反序列化字典

使用 protobuf-net 反序列化不同的列表