MassTransit消费AWS SQS消息时反序列化失败如何解决?
问题:MassTransit + AWS SQS 消费者反序列化后属性为空
基于.NET 6开发的项目,采用AWS SQS/SNS作为队列与主题。API应用负责发布消息到队列,控制台服务监听队列并消费消息。队列中消息内容显示正确,但消费者接收消息后,context.Message的所有属性均为NULL或空值,推测是反序列化环节出现异常。
API发布端配置
services.AddMassTransit(x => { x.SetKebabCaseEndpointNameFormatter(); x.UsingAmazonSqs((context, cfg) => { cfg.Host("some-region", h => { h.AccessKey(config.AccessKey); h.SecretKey(config.AccessSecret); h.Config(new AmazonSQSConfig() { RegionEndpoint = someregion }); }); cfg.ConfigureEndpoints(context); }); });
消费者控制台服务配置
services.AddMassTransit(x => { x.SetKebabCaseEndpointNameFormatter(); x.AddConsumer<CreateFeedbackCommandConsumer>(); x.AddCommands(); x.UsingAmazonSqs((context, cfg) => { cfg.Host("some-region", h => { h.AccessKey(sqsConfiguration.AccessKey); h.SecretKey(sqsConfiguration.AccessSecret); h.Config(new AmazonSQSConfig() { RegionEndpoint = someregion }); }); cfg.ReceiveEndpoint("create-feedback-command", endpoint => { endpoint.ConfigureConsumeTopology = false; endpoint.ClearSerialization(); endpoint.UseRawJsonSerializer(); endpoint.ConfigureConsumer<CreateFeedbackCommandConsumer>(context); }); cfg.ConfigureEndpoints(context); }); });
消费者代码
public class CreateFeedbackCommandConsumer : IConsumer<CreateFeedbackCommand> { private readonly ILogger<CreateFeedbackCommandConsumer> _logger; public CreateFeedbackCommandConsumer (ILogger<CreateFeedbackCommandConsumer> logger) { _logger = logger; } public async Task Consume(ConsumeContext<CreateFeedbackCommand> context) { try { var command = context.Message; _logger.LogInformation($"Incoming {nameof(CreateFeedbackCommand)}. CorrelationId: '{command.CorrelationId}'. DateTime (UTC): '{DateTime.UtcNow:dd-MMM-yyy hh:mm:ss}'"); if (command.Feedback == null) { throw new ArgumentNullException(nameof(command.Feedback)); } _logger.LogInformation($"Finished {nameof(CreateFeedbackCommand)}. CorrelationId: '{command.CorrelationId}'. DateTime (UTC): '{DateTime.UtcNow:dd-MMM-yyy hh:mm:ss}'"); } catch (Exception ex) { _logger.LogError(ex, $"An error has occurred while processing the {nameof(CreateFeedbackCommand)} command"); throw; } } }
命令类代码
public class CreateFeedbackCommand { public CreateFeedbackCommand(CreateFeedback feedback) { CorrelationId = Guid.NewGuid(); Feedback = feedback; } /// <summary> /// Unique Correlation ID. /// </summary> public Guid CorrelationId { get; set; } /// <summary> /// Feedback. /// </summary> public CreateFeedback Feedback { get; set; } }
解决方法
1. 统一两端序列化配置
发布端默认使用MassTransit自带的JsonSerializer(包含类型元数据),但消费者端强制启用了RawJsonSerializer,两者序列化逻辑不匹配导致反序列化失败。
- 方案一:消费者端对齐发布端配置
移除消费者端的序列化强制配置,保持与发布端一致:
cfg.ReceiveEndpoint("create-feedback-command", endpoint => { endpoint.ConfigureConsumeTopology = false; // 移除以下两行: // endpoint.ClearSerialization(); // endpoint.UseRawJsonSerializer(); endpoint.ConfigureConsumer<CreateFeedbackCommandConsumer>(context); });
- 方案二:两端同步使用RawJsonSerializer
如果业务需要使用RawJsonSerializer,发布端也需同步配置:
x.UsingAmazonSqs((context, cfg) => { // 现有Host配置 cfg.ClearSerialization(); cfg.UseRawJsonSerializer(); cfg.ConfigureEndpoints(context); });
2. 为命令类添加无参数构造函数
Json反序列化(无论默认还是RawJson)要求目标类具备公共无参数构造函数,当前CreateFeedbackCommand仅提供带参构造函数,导致反序列化时无法正常实例化对象,属性默认值为null/空。
修改命令类:
public class CreateFeedbackCommand { // 添加无参数构造函数 public CreateFeedbackCommand() {} public CreateFeedbackCommand(CreateFeedback feedback) { CorrelationId = Guid.NewGuid(); Feedback = feedback; } public Guid CorrelationId { get; set; } public CreateFeedback Feedback { get; set; } }
3. 检查嵌套类CreateFeedback的序列化兼容性
确保CreateFeedback类同样具备无参数构造函数,且所有需要反序列化的属性为公共可读写状态,无特殊序列化限制。
内容的提问来源于stack exchange,提问作者A. Gh
相关产品推荐
相关产品推荐

