114

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.

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();
Dale K
  • 25,246
  • 15
  • 42
  • 71
Chetan Goenka
  • 1,209
  • 2
  • 11
  • 17
  • What have you tries so far? Do you have this working for a single recipient? – Brendan Green May 06 '14 at 02:02
  • @BrendanGreen yes i have working for Single recipient. – Chetan Goenka May 06 '14 at 02:04
  • 5
    Also, FYI, your `MailMessage` and `SmtpClient` instances need to be in `using` blocks. – John Saunders May 06 '14 at 03:14
  • 3
    @JohnSaunders They should, but definately don't _need to_. – Num Lock May 29 '17 at 10:53
  • @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. – John Saunders May 29 '17 at 11:04
  • 1
    @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. – Num Lock May 29 '17 at 11:24

6 Answers6

215

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 "address1@example.com;address2@example.com".

Brendan Green
  • 11,676
  • 5
  • 44
  • 76
  • 66
    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. –  Apr 13 '15 at 21:05
  • 1
    @Areks, if you can put together a line of sample code similar to Brendan, you should definitely add that as an answer. – Adam Miller May 27 '15 at 19:50
  • @Areks thanks for this comment, i was allready splitting the adresses until i read your comment. this is exactly what i want! – Djeroen Jul 19 '16 at 07:27
  • 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. – Casey ScriptFu Pharr Aug 30 '17 at 02:56
  • @CaseyScriptFuPharr Because the source string is using semicolons as a separator and MailAddress accepts only comma-separated lists, not semicolon-separated lists. – TylerH Jul 28 '22 at 20:33
102

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.

  • 2
    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. – David Jacobsen Jun 24 '15 at 17:35
  • 1
    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! –  Jun 24 '15 at 18:33
  • 1
    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. – xr280xr Oct 28 '15 at 20:24
  • 1
    The format sadly appears to be not documented but the constructor does state it can be for more than one recipient: https://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". –  Oct 29 '15 at 00:24
  • 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? – Malcolm Salvador Jul 20 '17 at 03:03
  • 1
    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. https://referencesource.microsoft.com/#System/net/System/Net/mail/MailAddressParser.cs,542ab7043da2bb26 – Sinjai Aug 10 '17 at 21:16
12

According to the Documentation :

MailMessage.To property - Returns MailAddressCollection that contains the list of recipients of this email message

Here MailAddressCollection has a in built method called

   public void Add(string addresses)

   1. Summary:
          Add a list of email addresses to the collection.

   2. Parameters:
          addresses: 
                *The email addresses to add to the System.Net.Mail.MailAddressCollection. Multiple
                *email addresses must be separated with a comma character (",").     

Therefore requirement in case of multiple recipients : Pass a string that contains email addresses separated by comma

In your case :

simply replace all the ; with ,

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

For reference :

  1. https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.mailmessage?view=netframework-4.8
  2. https://www.geeksforgeeks.org/c-sharp-replace-method/
Shriram Navaratnalingam
  • 2,847
  • 2
  • 15
  • 20
1

This is how it worked for me :

            var addresses = "firstemail@email.com;secondemail@email.com";
            var fromAddress = new MailAddress("sender@email.com", "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);
                }
            }
0

You can use LINQ:

string toEmail = "name1@mydomain.com;name1@mydomain.com";
toEmail.Split(";").ToList().ForEach(address => Msg.To.Add(new MailAddress(address)));
David Najman
  • 487
  • 4
  • 7
-5

I've tested this using the following powershell script and using (,) between the addresses. It worked for me!

$EmailFrom = "<from@any.com>";
$EmailPassword = "<password>";
$EmailTo = "<to1@any.com>,<to2@any.com>";
$SMTPServer = "<smtp.server.com>";
$SMTPPort = <port>;
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer,$SMTPPort);
$SMTPClient.EnableSsl = $true;
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($EmailFrom, $EmailPassword);
$Subject = "Notification from XYZ";
$Body = "this is a notification from XYZ Notifications..";
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body);
  • 4
    That's a question tagged `C#`, not related to PowerShell at all – Jérôme MEVEL Nov 28 '18 at 03:15
  • Same library in the end. Its just easier to test using powershell on a machine with no vs. After you get the powersell script working it is just a matter of "translation" to the c# equivalent. – Heitor Marcos Nov 30 '18 at 18:25
  • 2
    This question isn't even tagged `.NET Framework` but only `C#`. If everybody was doing the same as you, we would also have VB.NET, F# or even C++ answers to all questions related to `.NET Framework`. After all it's the same Framework, it's just a matter of translation... You see my point here? StackOverflow would become a really trash source of information – Jérôme MEVEL Dec 02 '18 at 03:45