rabbitmq 为什么当合约在一个nuget包中时,Masstransit消费者没有接收到对象内部的对象

o8x7eapl  于 2023-08-05  发布在  RabbitMQ
关注(0)|答案(2)|浏览(105)

我有一个Masstransit出版商和一个消费者(都在下面)。
发送的消息是

public class SendEmailContract
    {
        public List<Attachment> Attachments { get; internal set; }
        public string AddressFrom { get; internal set; }
        public string AddressTo { get; internal set; }
        public string AddressCC { get; internal set; }
        public string AddressBCC { get; internal set; }
        public string Subject { get; internal set; }
        public string Data { get; internal set; }
        public string TemplateCode { get; internal set; }
        public string EmailHtml { get; internal set; }
        public bool WithoutTemplate { get; internal set; }
    }

    public class Attachment
    {
        public string Name { get; internal set; }
        public string ContentType { get; internal set; }
        public byte[] Content { get; internal set; }
    }

字符串
电子邮件合同具有附件列表。
当我运行示例发布者时,消费者将收到电子邮件合同和附件。
当电子邮件合约在nuget包中时(即在单独的DLL中),接收到电子邮件合同,但是附件为空。

问题当合同在单独的DLL中时,为什么附件字段为空?(这个问题可能很模糊,但我不知道如何进一步减少这个问题,任何帮助和想法将不胜感激)

下面的出版商

using MassTransit;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace ConsolePublisher
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                cfg.Host("localhost", "/", h =>
                {
                    h.Username("guest");
                    h.Password("guest");
                });


            });
            var source = new CancellationTokenSource(TimeSpan.FromSeconds(10));

            await busControl.StartAsync(source.Token);

            var message = new SendEmailContract
            {
                AddressFrom = "addressfrom@mail.com",
                AddressTo = "addressto@mail.com",
                AddressCC = "cc1@mail.com,cc2@email.com",
                AddressBCC = "bcc1@mail.com,bcc2@mail.com,bcc3@mail.com",
                Subject = $"Test subject email {DateTime.Now}",
                Data = @"<Data><CustomerName>NewReg NewReg</CustomerName><Barcode>bc12345678us</Barcode><URL>https://example.com</URL><ServiceTitle>Priority</ServiceTitle></Data>",
                TemplateCode = "emailtemplate123",
                EmailHtml = "emailhtml",
                WithoutTemplate = false,
                Attachments = new List<Attachment>
                {
                    new Attachment
                    {
                        Name = "Attachment1.txt",
                        ContentType = "txt",
                        Content = new byte[] { 1,2,3,4,5,6},
                    },
                    new Attachment
                    {
                        Name = "Attachment2.txt",
                        ContentType = "txt",
                        Content = new byte[] { 2,2,3,4,5,7},
                    }
                },
            };
            await busControl.Publish<SendEmailContract>(message);

            await busControl.StopAsync();

        }

    }

    public class SendEmailContract
    {
        public string AddressFrom { get; internal set; }
        public string AddressTo { get; internal set; }
        public string AddressCC { get; internal set; }
        public string AddressBCC { get; internal set; }
        public string Subject { get; internal set; }
        public string Data { get; internal set; }
        public string TemplateCode { get; internal set; }
        public string EmailHtml { get; internal set; }
        public bool WithoutTemplate { get; internal set; }
        public List<Attachment> Attachments { get; internal set; }
    }

    public class Attachment
    {
        public string Name { get; internal set; }
        public string ContentType { get; internal set; }
        public byte[] Content { get; internal set; }
    }
}


消费者下面

using GreenPipes;
using MassTransit;
using MassTransit.ConsumeConfigurators;
using MassTransit.Definition;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ConsuleConsumer
{

    public class Program
    {
        public static async Task Main(string[] args)
        {

            var services = new ServiceCollection();

            services.AddMassTransit(x =>
            {

                x.AddConsumer<EmailConsumer>(typeof(EmailConsumerDefinition));
                x.SetKebabCaseEndpointNameFormatter();
                x.UsingRabbitMq((context, cfg) =>
                {
                    cfg.Host("rabbitmq://localhost");
                    cfg.ConfigureEndpoints(context);
                });

            });

            var serviceProvider = services.BuildServiceProvider();
            var bus = serviceProvider.GetRequiredService<IBusControl>();

            await bus.StartAsync();

            Console.WriteLine("Press any key to exit");
            await Task.Run(() => Console.ReadKey());

            Console.WriteLine("Now stopping bus...");
            await bus.StopAsync();
            Console.WriteLine("Bus stopped");

            Console.ReadKey();
        }
    }

    public class EmailConsumer :
IConsumer<ConsolePublisher.SendEmailContract>
    {
        readonly ILogger<EmailConsumer> _logger;

        public EmailConsumer ()
        {
            Console.WriteLine("starting email consumer");
        }
        public EmailConsumer(ILogger<EmailConsumer> logger)
        {
            _logger = logger;
        }

        public async Task Consume(ConsumeContext<ConsolePublisher.SendEmailContract> context)
        {
            _logger.LogInformation("Email:", context.Message.Data);

        }
    }

    public class EmailConsumerDefinition :
    ConsumerDefinition<EmailConsumer>
    {
        public EmailConsumerDefinition()
        {
            // override the default endpoint name
            EndpointName = "email-service";

        }

        protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
            IConsumerConfigurator<EmailConsumer> consumerConfigurator)
        {
            endpointConfigurator.UseScheduledRedelivery(r => r.Intervals(TimeSpan.FromSeconds(10)));

            endpointConfigurator.UseInMemoryOutbox();
        }
    }

}

namespace ConsolePublisher
{
    public class SendEmailContract
    {
        public string AddressFrom { get; internal set; }
        public string AddressTo { get; internal set; }
        public string AddressCC { get; internal set; }
        public string AddressBCC { get; internal set; }
        public string Subject { get; internal set; }
        public string Data { get; internal set; }
        public string TemplateCode { get; internal set; }
        public string EmailHtml { get; internal set; }
        public bool WithoutTemplate { get; internal set; }
        public List<Attachment> Attachments { get; internal set; }
    }

    public class Attachment
    {
        public string Name { get; internal set; }
        public string ContentType { get; internal set; }
        public byte[] Content { get; internal set; }
    }

}


}


发布服务器中使用的版本

  1. MassTransit.RabbitMQ 8.0.5
    在消费者中使用的版本
  2. MassTransit.RabbitMQ 7.0.6

更新

1.如果我在发布服务器中使用MassTransit.RabbitMQ 7.0.6,问题就解决了。
1.当发布者使用版本8.0.5时,如果我关闭消费者并在RabbitMQ网站(http://localhost:15672/)中获取消息,则附件丢失。

56lgkhnf

56lgkhnf1#

MassTransit v8默认使用System.Text.Json,它不会反序列化为internal set;方法。它也在文档中被调用。您应该{ get; set; }以确保属性正确地序列化和反序列化。
当类在NuGet包中时,它不再是应用程序的“内部”。

snvhrwxg

snvhrwxg2#

我们通过在启动时配置RabbitMQ时将options.IncludeFields = true;添加到Json Serializer选项来修复此问题

cfg.ConfigureJsonSerializerOptions(options =>
                {
                    options.IncludeFields = true;
                    options.DefaultIgnoreCondition = JsonIgnoreCondition.Never;
                    return options;
                });

字符串

相关问题