【问题标题】:Rebus RabbitMQ Object serializationRebus RabbitMQ 对象序列化
【发布时间】:2017-08-23 15:39:47
【问题描述】:

当我通过 rebus 向 RabbitMQ 发送消息时,为什么它正在添加额外的对象数据,如下所示,主要是 $type。

{"$type":"ThreeSquared.VTGPAM.Objects.Wagon, ThreeSquared.VTGPAM.Objects","WagonId":"a98a06ab-33b9-4a11-9de2-df0b8787b713","WamosId":12324,"Description":"test","YearBuilt":1982,"Token":"3cce443c-249f-4fd2-9882-5830fb308b6b"}

我们有一个客户端,它将只使用 Java RabbitMQ 库而没有 rebus。这种方法我相信我们只是发送没有类型声明的 JSON。因此,当我尝试读取简单的 JSON 对象时,这不起作用。我们怎样才能让它工作,这样它就不会在消息中定义 $type 了?

【问题讨论】:

  • 什么不起作用 - 附加字段不应该不会影响它们吗?

标签: c# rabbitmq rebus


【解决方案1】:

这仅仅是因为 Rebus 默认使用带有 TypeNameHandling.All 的 Newtonsoft JSON.NET,这意味着 $type 字段包含在每个包含序列化类型的完整 .NET 类型名称的序列化对象中。

好处是您可以序列化几乎任何东西,即使它可能包含由(可能是抽象的)超类型甚至接口引用的实例。

例如此命令消息类型

public class ProcessFile
{
    public ProcessFile(string filePath, IEnumerable<IFileProcessingTask> tasks)
    {
        FilePath = filePath;
        Tasks = tasks;
    }

    public string FilePath { get; }

    public IReadOnlyCollection<IFileProcessingTask> Tasks { get; }
}

可以包含IFileProcessingTask 的任意实现,例如像

public class GZipFileProcessingTask : IFileProcessingTask
{
    // ...    
}

只要收件人可以通过$type 字段的值查找类型即可。

如果你想在另一个平台上处理这种类型的消息,你可以简单地让它忽略每个对象的$type字段。这可能很容易/很难/不可能,具体取决于您的 JSON 序列化程序的灵活性。

另一种选择是简单地用你自己的实现替换 Rebus 的序列化器

Configure.With(...)
    .(...)
    .Serialization(s => s.UseCustomJsonSerialization())
    .Start();

UseCustomJsonSerialization 是一个扩展方法,您可以这样实现:

public static class RebusConfigEx
{
    public static void UseCustomJsonSerialization(this StandardConfigurer<ISerializer> configurer)
    {
        configurer.Register(c => new YourCustomJsonSerializer());
    }
}

然后剩下要做的就是创建类YourCustomJsonSerializer作为ISerializer的实现。

【讨论】:

  • 我刚刚添加了这个删除它.Serialization(x =&gt; x.UseNewtonsoftJson(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None }))
猜你喜欢
  • 1970-01-01
  • 2012-01-14
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多