Browse Source

Merge pull request #17437 from abpframework/mail

Support attachments and `ExtraProperties` when sending emails.
pull/17545/head
Halil İbrahim Kalkan 3 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; `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). * **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**. * **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. > `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; EmailSender = emailSender;
} }
public override async Task ExecuteAsync(BackgroundEmailSendingJobArgs args) public async override Task ExecuteAsync(BackgroundEmailSendingJobArgs args)
{ {
if (args.From.IsNullOrWhiteSpace()) 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 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;
using System.Collections.Generic;
using Volo.Abp.Data;
namespace Volo.Abp.Emailing; namespace Volo.Abp.Emailing;
@ -18,5 +20,7 @@ public class BackgroundEmailSendingJobArgs
/// </summary> /// </summary>
public bool IsBodyHtml { get; set; } = true; 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;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail; using System.Net.Mail;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundJobs;
using Volo.Abp.Data;
namespace Volo.Abp.Emailing; namespace Volo.Abp.Emailing;
@ -24,20 +28,33 @@ public abstract class EmailSenderBase : IEmailSender
BackgroundJobManager = backgroundJobManager; 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 await SendAsync(BuildMailMessage(null, to, subject, body, isBodyHtml, attachments, extraProperties));
{
To = { to },
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
});
} }
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) public virtual async Task SendAsync(MailMessage mail, bool normalize = true)
@ -50,11 +67,11 @@ public abstract class EmailSenderBase : IEmailSender
await SendEmailAsync(mail); 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()) if (!BackgroundJobManager.IsAvailable())
{ {
await SendAsync(to, subject, body, isBodyHtml); await SendAsync(to, subject, body, isBodyHtml, attachments, extraProperties);
return; return;
} }
@ -64,16 +81,18 @@ public abstract class EmailSenderBase : IEmailSender
To = to, To = to,
Subject = subject, Subject = subject,
Body = body, 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()) if (!BackgroundJobManager.IsAvailable())
{ {
await SendAsync(from, to, subject, body, isBodyHtml); await SendAsync(from, to, subject, body, isBodyHtml, attachments, extraProperties);
return; return;
} }
@ -84,7 +103,9 @@ public abstract class EmailSenderBase : IEmailSender
To = to, To = to,
Subject = subject, Subject = subject,
Body = body, 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 System.Threading.Tasks;
using Volo.Abp.Data;
namespace Volo.Abp.Emailing; namespace Volo.Abp.Emailing;
@ -15,7 +17,9 @@ public interface IEmailSender
string to, string to,
string? subject, string? subject,
string? body, string? body,
bool isBodyHtml = true bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
); );
/// <summary> /// <summary>
@ -26,7 +30,9 @@ public interface IEmailSender
string to, string to,
string? subject, string? subject,
string? body, string? body,
bool isBodyHtml = true bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
); );
/// <summary> /// <summary>
@ -49,7 +55,9 @@ public interface IEmailSender
string to, string to,
string subject, string subject,
string body, string body,
bool isBodyHtml = true bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
); );
/// <summary> /// <summary>
@ -60,8 +68,8 @@ public interface IEmailSender
string to, string to,
string subject, string subject,
string body, 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()) 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; SmtpConfiguration = smtpConfiguration;
} }
protected override async Task SendEmailAsync(MailMessage mail) protected async override Task SendEmailAsync(MailMessage mail)
{ {
using (var client = await BuildClientAsync()) using (var client = await BuildClientAsync())
{ {

Loading…
Cancel
Save