在消息中检测到不匹配的组标签 - protobuf-net

时间:2010-02-10 11:00:17

标签: serialization protobuf-net

我对Silverlight很新。我正在为一个主要依赖于序列化和反序列化的项目工作。

以前,对于WPF,我对Serializable类感到满意。对于silverlight,我发现protobuf非常有用。但是,我对这个例外感到困扰。我不知道是什么原因引起了这个问题。请帮帮我。

我正在使用Silverlight 3.0。 protobuf-net r282

请找到我正在使用的代码。

[ProtoContract]
public class Report
{
    public Report()
    {
    }

    [ProtoMember(1)]
    public SubReports SubReports { get; set; }
}

[ProtoContract]
public class SubReports
   : List<SubReport>
{
    public SubReports()
    {
    }

    [ProtoMember(1)]
    public SubReport SubReport { get; set; }
}

[ProtoContract]
public class SubReport
{
    public SubReport()
    {
    }

    [ProtoMember(1)]
    public string Name { get; set; }
}

我用来反序列化的代码是

    public static T Deserialize<T>(Byte[] bytes) where T
        : Report
    {
        return ProtoBuf.Serializer.Deserialize<T>(new MemoryStream(bytes));
    }

我的示例XML看起来类似于

Report  
   ...SubReports  
      ...SubReport Name=”Q1 Report”   
      ...SubReport Name=”Q2 Report”   
      ...SubReport Name=”Q3 Report”   
      ...SubReport Name=”Q4 Report”     

提前致谢。
Vinodh

1 个答案:

答案 0 :(得分:1)

(注意:我无法重现“群组代码”问题;请参阅编辑历史记录以了解我对此的第一个想法,现已删除;如果您可以帮我重现这一点,我将不胜感激)

问题是SubReports。您已将此 both 定义为列表作为序列化实体([ProtoContract]);后者优先,所以它试图序列化列表上的单个子报告(总是null?)。

如果您将其更改为:

// note no attributes, no child property
public class SubReports : List<SubReport> { }

或者如果您完全删除它并使Report.SubReports成为List<SubReport>它应该可以正常工作。以下作品:

static void Main() {
    byte[] blob;
    // store a report
    using (MemoryStream ms = new MemoryStream()) {
        Report report = new Report {
            SubReports = new List<SubReport> {
                new SubReport { Name="Q1"}, 
                new SubReport { Name="Q2"},
                new SubReport { Name="Q3"},
                new SubReport { Name="Q4"},
            }
        };

        Serializer.Serialize(ms, report);
        blob = ms.ToArray();
    }
    // show the hex
    foreach (byte b in blob) { Console.Write(b.ToString("X2")); }
    Console.WriteLine();

    // reload it
    using (MemoryStream ms = new MemoryStream(blob)) {
        Report report = Serializer.Deserialize<Report>(ms);
        foreach (SubReport sub in report.SubReports) {
            Console.WriteLine(sub.Name);
        }
    }
}

显示blob:

  

0A040A0251310A040A0251320A040A0251330A040A025134