基于接口的Protobuf-net序列化

发布于 2024-09-19 12:29:17 字数 2473 浏览 8 评论 0原文

我正在使用 protobuf-net r282,当我调用 Serialize 时,我收到 InvalidOperationException 错误消息“只能处理数据契约类(及其列表/数组)(错误处理对象)”。在调用 protobuf-net Serializer.Serialize 时,相关对象已被转换为接口。有办法解决这个问题吗?

这是代码:

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using ProtoBuf;
using System;

namespace EventStore.Core
{
public interface Message
{
}

public interface Event : Message
{
    Guid Id { get; set; }

    int Version { get; set; }
}

[DataContract]
public class InventoryItemCreated : Event
{
    [DataMember(Order = 1)]
    public Guid Id { get; set; }

    [DataMember(Order = 2)]
    public int Version { get; set; }

    [DataMember(Order = 3)]
    public string Name { get; set; }

    public InventoryItemCreated(Guid id, string name)
    {
        Id = id;
        Name = name;
    }

    public InventoryItemCreated()
    {

    }
}

public class DefaultSerializer
{
    private readonly IFormatter formatter = new BinaryFormatter();

    public byte[] Serialize<T>(T graph) where T : class
    {
        if (default(T) == graph)
            return null;

        using (var stream = new MemoryStream())
        {
            this.Serialize(graph, stream);
            return stream.ToArray();
        }
    }

    public virtual void Serialize<T>(T graph, Stream output) where T : class
    {
        this.formatter.Serialize(output, graph);
    }

    public T Deserialize<T>(byte[] serialized) where T : class
    {
        if (null == serialized || 0 == serialized.Length)
            return default(T);

        using (var stream = new MemoryStream(serialized))
            return this.Deserialize<T>(stream);
    }

    public virtual T Deserialize<T>(Stream input) where T : class
    {
        return (T)this.formatter.Deserialize(input);
    }
}

public class ProtoBufSerializer : DefaultSerializer
{
    public override void Serialize<T>(T graph, Stream output)
    {
        Serializer.Serialize<T>(output, graph);
    }

    public override T Deserialize<T>(Stream input)
    {
        return Serializer.Deserialize<T>(input);
    }
}

class Program
{
    static void Main(string[] args)
    {
        ProtoBufSerializer serializer = new ProtoBufSerializer();
        InventoryItemCreated item = new InventoryItemCreated(Guid.NewGuid(), "Widget");
        byte[] buffer = serializer.Serialize((Message)item);
    }
}

}

I am using protobuf-net r282 and when I call Serialize I get the InvalidOperationException error message "Only data-contract classes (and lists/arrays of such) can be processed (error processing Object)". At the point where protobuf-net Serializer.Serialize is being called the object in question has been cast to an interface. Is there a way to get around this?

Here's the code:

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using ProtoBuf;
using System;

namespace EventStore.Core
{
public interface Message
{
}

public interface Event : Message
{
    Guid Id { get; set; }

    int Version { get; set; }
}

[DataContract]
public class InventoryItemCreated : Event
{
    [DataMember(Order = 1)]
    public Guid Id { get; set; }

    [DataMember(Order = 2)]
    public int Version { get; set; }

    [DataMember(Order = 3)]
    public string Name { get; set; }

    public InventoryItemCreated(Guid id, string name)
    {
        Id = id;
        Name = name;
    }

    public InventoryItemCreated()
    {

    }
}

public class DefaultSerializer
{
    private readonly IFormatter formatter = new BinaryFormatter();

    public byte[] Serialize<T>(T graph) where T : class
    {
        if (default(T) == graph)
            return null;

        using (var stream = new MemoryStream())
        {
            this.Serialize(graph, stream);
            return stream.ToArray();
        }
    }

    public virtual void Serialize<T>(T graph, Stream output) where T : class
    {
        this.formatter.Serialize(output, graph);
    }

    public T Deserialize<T>(byte[] serialized) where T : class
    {
        if (null == serialized || 0 == serialized.Length)
            return default(T);

        using (var stream = new MemoryStream(serialized))
            return this.Deserialize<T>(stream);
    }

    public virtual T Deserialize<T>(Stream input) where T : class
    {
        return (T)this.formatter.Deserialize(input);
    }
}

public class ProtoBufSerializer : DefaultSerializer
{
    public override void Serialize<T>(T graph, Stream output)
    {
        Serializer.Serialize<T>(output, graph);
    }

    public override T Deserialize<T>(Stream input)
    {
        return Serializer.Deserialize<T>(input);
    }
}

class Program
{
    static void Main(string[] args)
    {
        ProtoBufSerializer serializer = new ProtoBufSerializer();
        InventoryItemCreated item = new InventoryItemCreated(Guid.NewGuid(), "Widget");
        byte[] buffer = serializer.Serialize((Message)item);
    }
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄荷港 2024-09-26 12:29:17

这是我一直在寻找“v2”的东西,但它不完整。我已经收到了 v1 的补丁,它可以做到这一点,我可以分享它,但我还没有对此进行严格的测试。如果您需要此补丁文件,请告诉我。

This is something that I have been looking at for "v2", but it is incomplete. I have been sent a patch for v1 that does this and which I can share, but I haven't rigorously tested this. Let me know if you want this patch file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文