Browse Source

Merge pull request #17437 from abpframework/mail

Support attachments and `ExtraProperties` when sending emails.
pull/17545/head
Halil İbrahim Kalkan 2 years ago
committed by GitHub
parent
commit
c17c4c261d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      docs/en/Emailing.md
  2. 6
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs
  3. 6
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJobArgs.cs
  4. 11
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailAttachment.cs
  5. 53
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderBase.cs
  6. 22
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/IEmailSender.cs
  7. 2
      framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs
  8. 2
      framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs

5
docs/en/Emailing.md

@ -58,7 +58,12 @@ namespace MyProject
`SendAsync` method has overloads to supply more parameters like;
* **from**: You can set this as the first argument to set a sender email address. If not provided, the default sender address is used (see the email settings below).
* **to**: You can set the target email address.
* **subject**: You can set the email subject.
* **body**: You can set the email body.
* **isBodyHtml**: Indicates whether the email body may contain HTML tags. **Default: true**.
* **attachments**: You can pass a list of `EmailAttachment` to add attachments to the email.
* **extraProperties**: You can pass extra properties and use these properties in your own `IEmailSender` implementation to implement more mail sending features.
> `IEmailSender` is the suggested way to send emails, since it makes your code provider independent.

6
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs

@ -15,15 +15,15 @@ public class BackgroundEmailSendingJob : AsyncBackgroundJob<BackgroundEmailSendi
EmailSender = emailSender;
}
public override async Task ExecuteAsync(BackgroundEmailSendingJobArgs args)
public async override Task ExecuteAsync(BackgroundEmailSendingJobArgs args)
{
if (args.From.IsNullOrWhiteSpace())
{
await EmailSender.SendAsync(args.To, args.Subject, args.Body, args.IsBodyHtml);
await EmailSender.SendAsync(args.To, args.Subject, args.Body, args.IsBodyHtml, args.Attachments, args.ExtraProperties);
}
else
{
await EmailSender.SendAsync(args.From!, args.To, args.Subject, args.Body, args.IsBodyHtml);
await EmailSender.SendAsync(args.From!, args.To, args.Subject, args.Body, args.IsBodyHtml, args.Attachments, args.ExtraProperties);
}
}
}

6
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJobArgs.cs

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Data;
namespace Volo.Abp.Emailing;
@ -18,5 +20,7 @@ public class BackgroundEmailSendingJobArgs
/// </summary>
public bool IsBodyHtml { get; set; } = true;
//TODO: Add other properties and attachments
public List<EmailAttachment>? Attachments { get; set; }
public ExtraPropertyDictionary? ExtraProperties { get; set; }
}

11
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailAttachment.cs

@ -0,0 +1,11 @@
using System;
namespace Volo.Abp.Emailing;
[Serializable]
public class EmailAttachment
{
public string? Name { get; set; }
public byte[]? File { get; set; }
}

53
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/EmailSenderBase.cs

@ -1,8 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Data;
namespace Volo.Abp.Emailing;
@ -24,20 +28,33 @@ public abstract class EmailSenderBase : IEmailSender
BackgroundJobManager = backgroundJobManager;
}
public virtual async Task SendAsync(string to, string? subject, string? body, bool isBodyHtml = true)
public virtual async Task SendAsync(string to, string? subject, string? body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
await SendAsync(new MailMessage
{
To = { to },
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
});
await SendAsync(BuildMailMessage(null, to, subject, body, isBodyHtml, attachments, extraProperties));
}
public virtual async Task SendAsync(string from, string to, string? subject, string? body, bool isBodyHtml = true)
public virtual async Task SendAsync(string from, string to, string? subject, string? body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
await SendAsync(new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml });
await SendAsync(BuildMailMessage(from, to, subject, body, isBodyHtml, attachments, extraProperties));
}
protected virtual MailMessage BuildMailMessage(string? from, string to, string? subject, string? body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
var message = from == null
? new MailMessage { To = { to }, Subject = subject, Body = body, IsBodyHtml = isBodyHtml }
: new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml };
if (attachments != null)
{
foreach (var attachment in attachments.Where(x => x.File != null))
{
var fileStream = new MemoryStream(attachment.File!);
fileStream.Seek(0, SeekOrigin.Begin);
message.Attachments.Add(new Attachment(fileStream, attachment.Name));
}
}
return message;
}
public virtual async Task SendAsync(MailMessage mail, bool normalize = true)
@ -50,11 +67,11 @@ public abstract class EmailSenderBase : IEmailSender
await SendEmailAsync(mail);
}
public virtual async Task QueueAsync(string to, string subject, string body, bool isBodyHtml = true)
public virtual async Task QueueAsync(string to, string subject, string body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
if (!BackgroundJobManager.IsAvailable())
{
await SendAsync(to, subject, body, isBodyHtml);
await SendAsync(to, subject, body, isBodyHtml, attachments, extraProperties);
return;
}
@ -64,16 +81,18 @@ public abstract class EmailSenderBase : IEmailSender
To = to,
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
IsBodyHtml = isBodyHtml,
Attachments = attachments,
ExtraProperties = extraProperties
}
);
}
public virtual async Task QueueAsync(string from, string to, string subject, string body, bool isBodyHtml = true)
public virtual async Task QueueAsync(string from, string to, string subject, string body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
if (!BackgroundJobManager.IsAvailable())
{
await SendAsync(from, to, subject, body, isBodyHtml);
await SendAsync(from, to, subject, body, isBodyHtml, attachments, extraProperties);
return;
}
@ -84,7 +103,9 @@ public abstract class EmailSenderBase : IEmailSender
To = to,
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
IsBodyHtml = isBodyHtml,
Attachments = attachments,
ExtraProperties = extraProperties
}
);
}

22
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/IEmailSender.cs

@ -1,5 +1,7 @@
using System.Net.Mail;
using System.Collections.Generic;
using System.Net.Mail;
using System.Threading.Tasks;
using Volo.Abp.Data;
namespace Volo.Abp.Emailing;
@ -15,7 +17,9 @@ public interface IEmailSender
string to,
string? subject,
string? body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);
/// <summary>
@ -26,7 +30,9 @@ public interface IEmailSender
string to,
string? subject,
string? body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);
/// <summary>
@ -49,7 +55,9 @@ public interface IEmailSender
string to,
string subject,
string body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);
/// <summary>
@ -60,8 +68,8 @@ public interface IEmailSender
string to,
string subject,
string body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);
//TODO: Add other Queue methods too. Problem: MailMessage is not serializable so can not be used in background jobs.
}

2
framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Smtp/SmtpEmailSender.cs

@ -67,7 +67,7 @@ public class SmtpEmailSender : EmailSenderBase, ISmtpEmailSender, ITransientDepe
}
}
protected override async Task SendEmailAsync(MailMessage mail)
protected async override Task SendEmailAsync(MailMessage mail)
{
using (var smtpClient = await BuildClientAsync())
{

2
framework/src/Volo.Abp.MailKit/Volo/Abp/MailKit/MailKitSmtpEmailSender.cs

@ -29,7 +29,7 @@ public class MailKitSmtpEmailSender : EmailSenderBase, IMailKitSmtpEmailSender
SmtpConfiguration = smtpConfiguration;
}
protected override async Task SendEmailAsync(MailMessage mail)
protected async override Task SendEmailAsync(MailMessage mail)
{
using (var client = await BuildClientAsync())
{

Loading…
Cancel
Save