Oscar Arango
Oscar Arango

Reputation: 113

ASP.NET Core 3 Passing List of Emails to Send Method Mailkit

I'm using MailKit to send emails for account confirmation and password reset. These operations work as intended, but now I'm trying to modify the same code to also send email notifications to all registered users but this is where I'm having issues.

I've built a List collection using the following code:

public List<string> UserList {
    get {
        var allUsers = userManager.Users;
        return allUsers.Select(x => x.Email).ToList();
    }
}

this collection returns all emails within my AspNetUsers table successfully.

Next I create 3 variables:

var toAddress = UserList;
var subject = "New Asset Added" + " " + model.Name;
var body = model.Name + model.AssetType + model.AssetURL;

When debugging and stepping through the code I do see Count = 2 and then the list of emails in the variable. So far this looks good

After the 3 variables I have this line of code that passes the collected information to the Send method:

_emailSender.Send(toAddress[0], subject, body);

Again, the toAddress[0] when stepping through code shows Count = 2 so I'm assuming the way I have it written is valid.

Once I reach the Send Method code and I check the toAddress variable again, it is now stripped of the Count = 2 and becomes just the first email address in the list which makes sense since I passed the variable with an index of 0. What I really need is to pass all emails not just 1.

If I remove the brackets or leave the brackets empty I get an error:

cannot convert from 'System.Collections.Generic.List<string>' to 'string'

So for now I'm forced to add an index.

My send method seems fairly simple but I do believe my foreach loop might also not be well formulated. Here's my Send Method in it's entirety.

public async void Send(string toAddress, string subject, string body, bool sendAsync = true) {
    var mimeMessage = new MimeMessage(); // MIME : Multipurpose Internet Mail Extension
    mimeMessage.From.Add(new MailboxAddress(_fromAddressTitle, _fromAddress));

    foreach (char toAddresses in toAddress) {
        mimeMessage.To.Add(new MailboxAddress(toAddresses)); //I get error saying cannot convert char to string.  
    }

    mimeMessage.Subject = subject;

    var bodyBuilder = new MimeKit.BodyBuilder {
        HtmlBody = body
    };

    mimeMessage.Body = bodyBuilder.ToMessageBody();

    using (var client = new MailKit.Net.Smtp.SmtpClient()) {
        client.Connect(_smtpServer, _smtpPort, _enableSsl);

        client.Authenticate(_username, _password); // If using GMail this requires turning on LessSecureApps : https://myaccount.google.com/lesssecureapps
        if (sendAsync) {
            await client.SendAsync(mimeMessage);
        }
        else {
            client.Send(mimeMessage);
        }

        client.Disconnect(true);
    }
}

My end goal is to use a foreach loop on the mimeMessage.To.Add(new MailboxAddress(toAddresses)); so that everyone can receive an email if there is more than 1 email address, if not it can loop once.

Thanks in advance!

Upvotes: 1

Views: 2411

Answers (1)

Jawad
Jawad

Reputation: 11364

In your method, Send(), you are taking in a string for toAddress and then splitting its characters... that wont work. If you want to to use one or more email addresses, you will need to send in email address(es) separated by a delimiter or as a complete list.

Two ways to go about it.

Change the argument from string to List

  1. change your method to take in a List
public async void Send(List<string> toAddress, string subject, string body, bool sendAsync = true)
{
    var mimeMessage = new MimeMessage(); // MIME : Multipurpose Internet Mail Extension
    mimeMessage.From.Add(new MailboxAddress(_fromAddressTitle, _fromAddress));

    toAddress.ForEach(address => mimeMessage.To.Add(new MailboxAddress(address)));
...

if you use this method, you will need to send in the list as well.. not a single email address string.

List<string> toAddress = new List<string>() { "firstEmail", "Second" ...};
_emailSender.Send(toAddress, subject, body);

// You will not be able to do send in single string
_emailSender.Send("[email protected]", subject, body); //Exception no method found.

Send in a delimited list

  1. Always send in comma separated email addresses and translate those to multiple addresses when adding them to To field of your mimeMessage.
public async void Send(string toAddress, string subject, string body, bool sendAsync = true)
{
    var mimeMessage = new MimeMessage(); // MIME : Multipurpose Internet Mail Extension
    mimeMessage.From.Add(new MailboxAddress(_fromAddressTitle, _fromAddress));

    // HERE -> FOREACH string, not char.
    foreach (string toAddresses in toAddress.Split(',')) // Split on ,
    {
        mimeMessage.To.Add(new MailboxAddress(toAddresses)); 
    }

and you will need to use this method the following way...

List<string> toAddress = new List<string>() {"first", "..."};
_emailSender.Send(string.Join(',',toAddress), subject, body);

Upvotes: 3

Related Questions