首页 > 解决方案 > 使用不正确的 JSON 格式处理 MassTransit 互操作错误

问题描述

我们使用非 .NET 客户端将我们的一些公共 API 与使用 MassTransit 互操作的后端 .NET 服务集成,并且我们会定期收到不符合消息规范的请求(例如,客户端在我们期望对象的位置提供字符串)。这会ArgumentException按预期导致 xxx_error 队列中的 s ,并且我可以看到具有错误属性的原始消息。我希望有一种方法可以使用和处理这些,这样我就可以“手动”反序列化它们,检查它们的一些属性,并通知客户他们正在发送错误消息。

我尝试使用处理Fault<T>消息类型的消费者,但这似乎也依赖于成功反序列化并且永远不会被调用的消息。我感兴趣的消息都有一个通用的基本接口,我试图为该接口创建一个错误使用者,希望绕过反序列化,但该错误使用者似乎也从未被调用。

我还尝试使用接收消息的非通用Fault消费者,但是如果我使用该消费者,我无法获取原始错误消息,因此我可以检查它。如果我使用它检查消息内容,context.ReceiveContext.GetBody()则它具有故障消息属性和异常,但没有原始消息详细信息。因此,使用其中一个TryGetMessage()TryGetPayload()返回 false。

代码示例来说明我在说什么:

// base interface
public interface IFoo { 
  Bar Bar { get; }
}

// message class
public class Foo : IFoo {
  public Bar Bar { get; set; }
}

// foo fault consumer - never called
public class FooFaultConsumer : IConsumer<Fault<Foo>>
{
  public Task Consume(ConsumeContext<Fault<Foo>> context) => context.CompleteTask;
}

// ifoo fault consumer - also never called
public class FooInterfaceFaultConsumer : IConsumer<Fault<IFoo>>
{
  public Task Consume(ConsumeContext<Fault<IFoo>> context) => context.CompleteTask;
}

// non-generic fault consumer - called but no details available
public class FaultConsumer : IConsumer<Fault>
{
  public Task Consume(ConsumeContext<Fault> context)
  {
    context.TryGetMessage(out IFoo _); // returns false
    context.TryGetMessage(out Foo _); // returns false
    context.TryGetPayload(out IFoo _); // returns false
    context.TryGetPayload(out Foo _); // returns false
    context.ReceiveContext.TryGetPayload(out IFoo _); // returns false
    context.ReceiveContext.TryGetPayload(out Foo _); // returns false

    var body = Encoding.UTF8.GetString(context.ReceiveContext.GetBody());

    // body is a JSON string with a message property that only has Fault properties 
    // it does not contain any of the original message properties
  }
}
// registrations
cfg.ReceiveEndpoint(e => {
  e.Consumer<FooFaultConsumer>();
  e.Consumer<FooInterfaceFaultConsumer>();
});

错误消息示例,其中 Bar 是字符串而不是对象(消息包含在 MassTransit 标头中)。

{
  "bar" : "foobar"
}

是否有一种优雅的方式来处理 JSON 反序列化错误并获取出现在错误队列中的消息副本?我注意到 MassTransit 文档建议不要将消费者置于这些队列中。

标签: c#jsonmessagingmasstransit

解决方案


推荐阅读