Open Closed

Smtp Tenant Setting not set to emailSender #9641


0
datalab created

Hello When i try to send email whit method SendCourseEnrollementEmail the emailSender use host configuration and not tenant configuration, if i use the test email from tenant ui Smtp Settings it work fine.

Best Regards

Prerequisites

se answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.

  • What is your product version? Module Zero 8.4.0
  • What is your product type (Angular or MVC)? angular
  • What is product framework type (.net framework or .net core)? .net Core 3.1

AllowTenantsToChangeEmailSettings = true* ` public class EcoSectConsts { public const string LocalizationSourceName = "EcoSect";

    public const string ConnectionStringName = "Default";

    public const bool MultiTenancyEnabled = true;

    public const bool AllowTenantsToChangeEmailSettings = true;

    public const string Currency = "EUR";

    public const string CurrencySign = "€";

    public const string AbpApiClientUserAgent = "AbpApiClient";

    // Note:
    // Minimum accepted payment amount. If a payment amount is less then that minimum value payment progress will continue without charging payment
    // Even though we can use multiple payment methods, users always can go and use the highest accepted payment amount.
    //For example, you use Stripe and PayPal. Let say that stripe accepts min 5$ and PayPal accepts min 3$. If your payment amount is 4$.
    // User will prefer to use a payment method with the highest accept value which is a Stripe in this case.
    public const decimal MinimumUpgradePaymentAmount = 1M;
}`

Application Service Method call Job
` [AbpAuthorize(AppPermissions.Pages_CourseLeads_SendEmail)]
    public async Task SendCourseEnrollementEmail(SendCourseEnrollementEmailInput input)
    {          
        using(CurrentUnitOfWork.SetTenantId(AbpSession.TenantId))
        { 
        await _backgroundJobManager.EnqueueAsync<SendCourseEnrollementEmailJob, SendCourseEnrollementEmailJobArgs>(
               new SendCourseEnrollementEmailJobArgs
               {
                   CourseId = input.CourseId,
                   CustomersIds = input.CustomersIds,
                   User = AbpSession.ToUserIdentifier(),
                   TenantId = AbpSession.TenantId
               });
        }
    }`
    
    Job Worker Code
    ` public override void Execute(SendCourseEnrollementEmailJobArgs args)
    {

        var courseLeads = _courseLeadRepository.GetAll()
                              .Include(e => e.Course)
                              .ThenInclude(e => e.CourseCategory)
                              .Include(e => e.Course)
                              .ThenInclude(e => e.CourseLocation)
                              .Include(e => e.Course)
                              .ThenInclude(e => e.CourseLessons)
                              .ThenInclude(e => e.Teacher)
                              .Include(e => e.Customer)
                              .Include(e => e.CourseLeadEmployees)
                              .ThenInclude(e => e.Employee)
                              .Where(e => e.CourseId == args.CourseId)
                              .WhereIf(args.CustomersIds.Count > 0, e => args.CustomersIds.Any(id => id == e.CustomerId))
                              .ToList();

        string courseName = courseLeads.FirstOrDefault()?.Course.Name;

        string invalidSendMessage = "Non è stato possibile inviare il messaggio al seguente destinatario {0} per il seguente motivo: {1}";

        foreach (var courseLead in courseLeads)
        {
            try
            {
                if (string.IsNullOrEmpty(courseLead.Customer?.MarketingEmail))
                {
                    AsyncHelper.RunSync(() => SendInvalidEmailNotification(args, string.Format(invalidSendMessage, courseLead.Customer.Name, "Al cliente non è stato impostato l'indirizzo Email Marketing.")));
                }
                else
                {
                    TryToSendCourseEnrollementEmailInput tryToSendCourseEnrollementEmailInput = new TryToSendCourseEnrollementEmailInput();
                    tryToSendCourseEnrollementEmailInput.TenantId = args.TenantId;
                    tryToSendCourseEnrollementEmailInput.CourseLead = courseLead;

                    AsyncHelper.RunSync(() => _courseEmailer.TryToSendCourseEnrollementEmail(tryToSendCourseEnrollementEmailInput));

                    courseLead.Status = CourseLeadStatus.SendedComunication;

                }

            }
            catch (UserFriendlyException exception)
            {
                AsyncHelper.RunSync(() => SendInvalidEmailNotification(args, string.Format(invalidSendMessage, courseLead.Customer.Name, exception.Message)));
            }
            catch (Exception exception)
            {
                AsyncHelper.RunSync(() => SendInvalidEmailNotification(args, string.Format(invalidSendMessage, courseLead.Customer.Name, exception.ToString())));
            }
        }

        AsyncHelper.RunSync(() => SendSurveyCompletedNotification(args, string.Format("L'invio delle email per il corso {0} è stato avviato.", courseName)));

    }`
    
    Course Emailer code TryToSendCourseEnrollementEmail
    `public async Task TryToSendCourseEnrollementEmail(TryToSendCourseEnrollementEmailInput input)
    {
        
        var emailTemplate = new StringBuilder(_emailTemplateProvider.GetCourseEnrollementTemplate(input.TenantId));
        var emailTransformed = TransformEmail(emailTemplate, input.CourseLead);

        await _emailSender.SendAsync(new MailMessage
        {
            To = { input.CourseLead.Customer.MarketingEmail },
            Subject = "Certificazioni in Scadenza",
            Body = emailTransformed,
            IsBodyHtml = true, 
            CC = { _ecoSectSmtpEmailSenderConfiguration.DefaultFromAddress },
        });
    }`
    
    

7 Answer(s)
  • 0
    datalab created

  • 0
    zony created
    Support Team

    Hi datalab, I think it is caused by the background job, because the current tenant information cannot be obtained when the background job is executed. You can use CurrentUnitOfWork.SetTenantId(tenantId) to switch to the corresponding tenant when the background job is executing. e.g.

    public override void Execute(ImportUsersFromExcelJobArgs args)
    {
        var users = GetUserListFromExcelOrNull(args);
        if (users == null || !users.Any())
        {
            SendInvalidExcelNotification(args);
            return;
        }
    
        CreateUsers(args, users);
    }
    
    private List<ImportUserDto> GetUserListFromExcelOrNull(ImportUsersFromExcelJobArgs args)
    {
        using (var uow = _unitOfWorkManager.Begin())
        {
            using (CurrentUnitOfWork.SetTenantId(args.TenantId))
            {
                try
                {
                    var file = AsyncHelper.RunSync(() => _binaryObjectManager.GetOrNullAsync(args.BinaryObjectId));
                    return _userListExcelDataReader.GetUsersFromExcel(file.Bytes);
                }
                catch (Exception)
                {
                    return null;
                }
                finally
                {
                    uow.Complete();
                }
            }
        }
    }
    
  • 0
    datalab created

    Hi zony i have try your solution but it not work, i have also try to resolve instance of EMail Sender inside the using block, but how you see in follow image it is not resolved by tenant.

  • 0
    zony created
    Support Team

    Hi datalab, Can you inject IAbpSession into BackgroundJob and check the TenantId property of IAbpSession. You put this code in the using block. e.g.

    var currentSession = IocManager.Resove<IAbpSession>();
    
  • 0
    datalab created

    Hi Zony TenatId is null :-(

  • 0
    ismcagdas created
    Support Team
  • 0
    datalab created

    Hi @ismcagdas Thanks You di solution work fine. I'have add _abpsession.using in BackgroundJob how in example. Best Regards