【问题标题】:protobuf-net - Serializing objects as properties of [ProtoContract] instances in arrayprotobuf-net - 将对象序列化为数组中 [ProtoContract] 实例的属性
【发布时间】:2013-06-11 09:16:13
【问题描述】:

有这样一种类型:

[ProtoContract(UseProtoMembersOnly=true)]
public class ProtoObjectDTO
{
    [ProtoMember(1, DynamicType=true)]
    public object Value { get; set; }
    [ProtoMember(2)]
    public int Order { get; set; }
}

这些对象的数组具有多个实例 (参数在以下 sn-p 中)发送到服务:

await client.PostAsync<ProtoObjectDTO[]>(
    route, parameters, new ProtoBufFormatter())
        .ContinueWith((r) =>
        {
            r.Result.EnsureSuccessStatusCode();

            retVal = true;
        });

parameters 包含两个具有 Value 属性的实例 设置为不同类型的有效[ProtoContract]对象。

当数据到达服务器端时,它会像这样被反序列化:

var sentParams = ProtoBuf.Serializer.Deserialize<ProtoObjectDTO[]>(stream);

当检查 sentParams 并与 parameters 进行比较时, Value 在第二个实例中只是一个默认实例 在第一个实例中的对象类型。这很奇怪。 你能帮我解决这个问题吗?谢谢。

【问题讨论】:

    标签: protobuf-net


    【解决方案1】:

    我添加了以下测试,它成功运行。要进行调查,似乎有必要提供有关所涉及类型的更多信息(或者理想情况下,测试失败):

    [ProtoContract]
    public class Foo
    {
        [ProtoMember(3)]
        public int A { get; set; }
    }
    [ProtoContract]
    public class Bar
    {
        [ProtoMember(4)]
        public string B { get; set; }
    }
    
    public void Execute()
    {
        var model = TypeModel.Create();
        model.AutoCompile = false;
    
        Execute(model, "Runtime");
        model.CompileInPlace();
        Execute(model, "CompileInPlace");
        Execute(model.Compile(), "Compile");
        model.Compile("SO17040488", "SO17040488.dll");
        PEVerify.AssertValid("SO17040488.dll");
    
    }
    
    private void Execute(TypeModel model, string caption)
    {
        var args = new[] {
            new ProtoObjectDTO { Order = 1, Value = new Foo { A = 123 }},
            new ProtoObjectDTO { Order = 2, Value = new Bar { B = "abc" }},
        };
        var clone = (ProtoObjectDTO[])model.DeepClone(args);
        Assert.AreEqual(2, clone.Length, caption + ":length");
        Assert.AreEqual(1, clone[0].Order, caption + ":order");
        Assert.AreEqual(2, clone[1].Order, caption + ":order");
        Assert.IsInstanceOfType(typeof(Foo), clone[0].Value, caption + ":type");
        Assert.IsInstanceOfType(typeof(Bar), clone[1].Value, caption + ":type");
        Assert.AreEqual(123, ((Foo)clone[0].Value).A, caption + ":value");
        Assert.AreEqual("abc", ((Bar)clone[1].Value).B, caption + ":value");
    }
    

    【讨论】:

    • 你好 Marc,我刚刚修复了这个错误。谢谢(也很抱歉)您的时间。我正在制作一个通用解决方案,用于在 ApiController-s 中使用 proto-buf 序列化启用非 REST 方法签名。在这种情况下,DynamicType=true 就像魅力一样 :)
    猜你喜欢
    • 1970-01-01
    • 2011-09-11
    • 2013-06-16
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 2011-12-04
    • 1970-01-01
    相关资源
    最近更新 更多