How to send email to multiple recipients with MailMessage
Asked Answered
D

5

118

I have multiple email recipients stored in SQL Server. When I click send in the webpage it should send email to all recipients. I have separated emails using ;.

Following is the single recipient code, which works:

MailMessage Msg = new MailMessage();
MailAddress fromMail = new MailAddress(fromEmail);
Msg.From = fromMail;
Msg.To.Add(new MailAddress(toEmail));

if (ccEmail != "" && bccEmail != "")
{
    Msg.CC.Add(new MailAddress(ccEmail));
    Msg.Bcc.Add(new MailAddress(bccEmail));
}

SmtpClient a = new SmtpClient("smtp server name");
a.Send(Msg);
sreader.Dispose();
Derivation answered 6/5, 2014 at 1:21 Comment(4)
Also, FYI, your MailMessage and SmtpClient instances need to be in using blocks.Orthodontics
@JohnSaunders They should, but definately don't need to.Dipteran
@num yeah, need to be. SmtpClient in particular has been known to not send until disposed. I had a Web app that wasn't disposing. We could measure 2 minutes before the message was actually sent.Orthodontics
@JohnSaunders First of all, your wording is very misleading: You will probably argue on this, but "needs to be in using blocks" does not equal "needs to be disposed". Second, in production code like web applications you will usually want to use SendAsync anyways, which works as intended without the need to dispose the SnmpClient instance.Dipteran
R
221

Easy!

Just split the incoming address list on the ";" character, and add them to the mail message:

foreach (var address in addresses.Split(new [] {";"}, StringSplitOptions.RemoveEmptyEntries))
{
    mailMessage.To.Add(address);    
}

In this example, addresses contains "[email protected];[email protected]".

Rosauraroscius answered 6/5, 2014 at 2:9 Comment(4)
I'm late to the party but the MailMessage(string from, string to) constructor accepts a comma-separated list of addresses. So, you could have done something like new MailMessage(fromMail, addresses.replace(";", ",")) Maybe it's not better to use replace, but I feel like I should comment this in case other people have already comma separated strings! Then would be no need for splitting or replacing.Severity
@Areks, if you can put together a line of sample code similar to Brendan, you should definitely add that as an answer.Marci
Is this necessary? Are you not just taking the string already formatted for multiple address and splitting them, then reassigning them? If you send To() a string as mentioned To("a1;a2;a3") why do you need to split them and then assign individually? Since it excepts multiple Addresses in AddressCollection or a deliminator string.Birl
@CaseyScriptFuPharr Because the source string is using semicolons as a separator and MailAddress accepts only comma-separated lists, not semicolon-separated lists.Shackelford
S
104

As suggested by Adam Miller in the comments, I'll add another solution.

The MailMessage(String from, String to) constructor accepts a comma separated list of addresses. So if you happen to have already a comma (',') separated list, the usage is as simple as:

MailMessage Msg = new MailMessage(fromMail, addresses);

In this particular case, we can replace the ';' for ',' and still make use of the constructor.

MailMessage Msg = new MailMessage(fromMail, addresses.replace(";", ","));

Whether you prefer this or the accepted answer it's up to you. Arguably the loop makes the intent clearer, but this is shorter and not obscure. But should you already have a comma separated list, I think this is the way to go.

Severity answered 1/6, 2015 at 6:49 Comment(6)
Since it caused an issue with an application that I manage that implemented this, you should check if the trailing character is a semi colon and remove that before running the replace command. I'm not sure if a trailing semicolon is considered a valid recipient list, but people may be used to seeing a trailing semicolon through applications like Outlook. You can't have a trailing comma in the comma separated list you pass to MailMessage.Bevvy
To my understanding there shouldn't be a trailing comma/semicolon if there's nothing after that... But definitely a good comment so people reading this are aware about it. Thank you!Severity
Is this documented somewhere? The constructor docs just describe the to param as "A String that contains the address of the recipient of the e-mail message". I want to use it but not if its support may be removed.Floaty
The format sadly appears to be not documented but the constructor does state it can be for more than one recipient: msdn.microsoft.com/en-us/library/14k9fb7t(v=vs.110).aspx A String that contains the addresses of the recipients of the e-mail message. It's plural for both "addresses" and "recipients".Severity
This did not work for me. I have tried separating by comma but no emails are sent. I tried debugging but it did not reveal any errors.. catch was not triggered. What could be the cause?Helminthiasis
Definitely a feature, but documentation is either sparse or nonexistent. I had to go through about 5 method calls just to get the first hint that it's true. referencesource.microsoft.com/#System/net/System/Net/mail/…Endoderm
F
15

According to the Microsoft Documentation, the MailMessage.To property:

Gets the address collection that contains the recipients of this email message.

This collection is in the form of a MailAddressCollection object, which has a built-in Add(string) method:

Add a list of email addresses to the collection.

public void Add (string addresses);

Parameters:

addresses - String

The email addresses to add to the MailAddressCollection. Multiple email addresses must be separated with a comma character (",").

As you can see, the e-mail addresses must be separated with commas, not semicolons. You can resolve the error with the replace() method:

Msg.To.Add(toEmail.replace(";", ","));

This will result in a comma-separated list of e-mail addresses.

Foe answered 17/4, 2020 at 6:34 Comment(0)
M
0

This is how it worked for me :

var addresses = "[email protected];[email protected]";
var fromAddress = new MailAddress("[email protected]", "Sender");
const string fromPassword = "Password";
string subject = "[Message] Message Subject" ;
string body = "Message Body";

var smtp = new SmtpClient
{
    Host = "smtp.email.com", 
    Port = 587, //or 25 depending on your smtp server config
    EnableSsl = true,
    DeliveryMethod = SmtpDeliveryMethod.Network,
    UseDefaultCredentials = false,
    Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
foreach (var address in addresses.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries))
{
using (var message = new MailMessage(fromAddress.ToString(), address)
{
    Subject = subject,
    Body = body,
    Priority = MailPriority.High
    
})
    {
    
        smtp.Send(message);
    }
}
Mournful answered 29/8, 2021 at 8:40 Comment(1)
Long code block-only answers are seldom helpful to readers. Please edit your answer to clarify exactly what your answer changes from OP's code and how that solves their problem.Shackelford
L
0

You can use LINQ:

string toEmail = "[email protected];[email protected]";
toEmail.Split(";").ToList().ForEach(address => Msg.To.Add(new MailAddress(address)));
Lewls answered 15/8, 2022 at 17:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.