You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

发送含MessageData<byte[]>集合的消息时消费端遇MassTransit加载异常

嘿,我之前也碰到过这个MassTransit.MessageDataException: The message data was not loaded的问题,咱们一步步来排查解决:

排查MassTransit MessageData未加载异常

1. 确保发送端与消费端的Enchilada存储配置完全一致

这是最常见的问题!发送端和消费端的MessageData存储配置必须完全匹配,包括存储类型(本地磁盘、S3、Azure Blob等)、路径/桶名称、权限配置。如果两端配置不一样,消费端根本找不到存储的MessageData文件,自然会抛出异常。

举个例子,发送端如果是这样配置本地磁盘存储:

services.AddMassTransit(x =>
{
    x.UsingRabbitMq((context, cfg) =>
    {
        cfg.MessageDataRepository(context, r =>
        {
            r.EnchiladaRepository(c =>
            {
                c.UseFileSystem("/app/attachments");
            });
        });
    });
});

那消费端必须用完全相同的路径(如果是本地存储,要确保消费进程有该路径的读写权限);如果是云存储,密钥、桶名、区域这些参数也必须完全一致。

2. 确认数组类型MessageData的发送处理

你用到了MessageData<byte[]>[]数组,发送时要确保每个数组元素都被正确上传到存储库,不能有遗漏。最好用Task.WhenAll等待所有附件上传完成后再发送消息,避免消息先被投递但部分附件还没写入存储的情况:

// 假设你有一组byte[]格式的附件内容
var attachmentContents = new List<byte[]> { ... };

// 逐个上传到MessageData存储
var messageDataAttachments = await Task.WhenAll(
    attachmentContents.Select(async content => 
        await _messageDataRepository.PutBytes(content, CancellationToken.None)
    )
);

// 构造消息并发送
var sendMailMessage = new SendMail
{
    Attachments = messageDataAttachments,
    AttachmentFileName = "example.pdf",
    // 其他属性...
};

await _bus.Publish(sendMailMessage);

3. 消费端正确加载MessageData数组

消费时,要注意MessageData<T>的Value属性是异步的,必须用await加载,数组类型需要逐个处理每个元素:

public class SendMailConsumer : IConsumer<ISendMail>
{
    private readonly IMessageDataRepository _messageDataRepository;

    public SendMailConsumer(IMessageDataRepository messageDataRepository)
    {
        _messageDataRepository = messageDataRepository;
    }

    public async Task Consume(ConsumeContext<ISendMail> context)
    {
        // 加载单个附件
        var singleAttachmentBytes = await context.Message.Attachment.Value;
        
        // 加载数组中的所有附件
        var allAttachmentBytes = await Task.WhenAll(
            context.Message.Attachments.Select(async md => await md.Value)
        );

        // 这里做你的邮件发送逻辑...
    }
}

如果跳过await直接访问Value,会因为加载未完成抛出异常。另外也要确保消费端正确注册了IMessageDataRepository,和发送端配置一致。

4. 检查MessageData的引用地址是否完整

有时候消息传输过程中,MessageData的存储地址(Address属性)可能被序列化/反序列化篡改。你可以在发送端打印每个MessageData的Address,然后在消费端对比:

发送端打印:

var attachment = await _messageDataRepository.PutBytes(content, CancellationToken.None);
Console.WriteLine($"发送端附件地址: {attachment.Address}");

消费端打印:

foreach(var md in context.Message.Attachments)
{
    Console.WriteLine($"消费端收到的附件地址: {md.Address}");
}

如果地址不一致,说明序列化配置有问题,比如自定义序列化器没有正确处理MessageData类型,建议检查MassTransit的序列化设置(默认Json序列化是支持MessageData的,如果你换了Protobuf等序列化器,需要确认是否兼容)。

5. 验证Enchilada存储的可用性

最后,确认消费端能访问到Enchilada的存储服务:

  • 如果是本地存储:检查路径是否存在,消费进程是否有读写权限;
  • 如果是云存储:确认密钥有效、网络连通、桶权限配置正确;
  • 手动检查存储位置是否存在发送端上传的文件,消费端能否直接读取该文件。

内容的提问来源于stack exchange,提问作者Arjan Verrmunt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:04:29