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
-
0
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
-
0
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
-
0
Hi @datalab,
Could you try this https://aspnetboilerplate.com/Pages/Documents/Abp-Session#user-identifier ?
Thanks,
-
0
Hi @ismcagdas Thanks You di solution work fine. I'have add _abpsession.using in BackgroundJob how in example. Best Regards