Enviar e-mail para vários destinatários com MailMessage?

87

Tenho vários destinatários de email armazenados no SQL Server. Quando clico em enviar na página da Web, ele deve enviar e-mail para todos os destinatários. Separei e-mails usando ;.

A seguir está o código do destinatário único.

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();
Chetan Goenka
fonte
O que você tentou até agora? Você tem isso funcionando para um único destinatário?
Brendan Green
@BrendanGreen sim, estou trabalhando para um destinatário único.
Chetan Goenka
5
Além disso, para sua informação, suas instâncias MailMessagee SmtpClientprecisam estar em usingblocos.
John Saunders
2
@JohnSaunders Deviam, mas definitivamente não precisam .
Num Lock
1
@JohnSaunders Em primeiro lugar, sua formulação é muito enganosa: você provavelmente argumentará sobre isso, mas "precisa estar em usingblocos" não é igual a "precisa ser eliminado". Em segundo lugar, em código de produção, como aplicativos da web, você geralmente desejará usar de SendAsyncqualquer maneira, o que funciona como pretendido, sem a necessidade de descartar a SnmpClientinstância.
Num Lock de

Respostas:

182

Fácil!

Apenas divida a lista de endereços de entrada no ";" caractere e adicione-os à mensagem de e-mail:

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

Neste exemplo, addressescontém " [email protected];[email protected]".

Brendan Green
fonte
56
Estou atrasado para a festa, mas o construtor MailMessage (string de, string para) aceita uma lista de endereços separados por vírgula. Então, você poderia ter feito algo como new MailMessage (fromMail, addresses.replace (";", ",")) Talvez não seja melhor usar substituir, mas acho que devo comentar isso caso outras pessoas já tenham se separado por vírgulas cordas! Então não haveria necessidade de divisão ou substituição.
Areks
@Areks, se você pode juntar uma linha de código de amostra semelhante a Brendan, você definitivamente deve adicionar isso como uma resposta.
Adam Miller de
@Areks, obrigado por este comentário, eu já estava dividindo os endereços até ler seu comentário. isso é exatamente o que eu quero!
Djeroen
Isso é necessário? Você não está apenas pegando a string já formatada para endereços múltiplos e dividindo-os e, em seguida, reatribuindo-os? Se você enviar para () uma string conforme mencionado para ("a1; a2; a3"), por que você precisa dividi-los e atribuir individualmente? Uma vez que ele exclui vários endereços em AddressCollection ou uma string deliminadora.
Casey
85

Conforme sugerido por Adam Miller nos comentários, adicionarei outra solução.

O construtor MailMessage (String from, String to) aceita uma lista de endereços separados por vírgulas. Então, se acontecer de você já ter uma lista separada por vírgulas (','), o uso é tão simples como:

MailMessage Msg = new MailMessage(fromMail, addresses);

Neste caso particular, podemos substituir o ';' para ',' e ainda usar o construtor.

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

Se você prefere esta ou a resposta aceita, depende de você. Indiscutivelmente, o loop torna a intenção mais clara, mas é mais curto e não obscuro. Mas se você já tiver uma lista separada por vírgulas, acho que esse é o caminho a percorrer.

Areks
fonte
2
Como isso causou um problema com um aplicativo que eu gerenciei e que implementou isso, você deve verificar se o caractere final é um ponto e vírgula e removê-lo antes de executar o comando replace. Não tenho certeza se um ponto-e-vírgula final é considerado uma lista de destinatários válida, mas as pessoas podem estar acostumadas a ver um ponto-e-vírgula final em aplicativos como o Outlook. Você não pode ter uma vírgula final na lista separada por vírgulas que você passar para MailMessage.
David Jacobsen
1
No meu entendimento, não deve haver uma vírgula / ponto-e-vírgula à direita se não houver nada depois disso ... Mas definitivamente um bom comentário para que as pessoas que estejam lendo isso fiquem cientes dele. Obrigado!
Areks
1
Isso está documentado em algum lugar? Os documentos do construtor apenas descrevem o toparâmetro como "Uma String que contém o endereço do destinatário da mensagem de e-mail". Quero usá-lo, mas não se o suporte puder ser removido.
xr280xr
1
Infelizmente, o formato não parece estar documentado, mas o construtor afirma que pode ser para mais de um destinatário: msdn.microsoft.com/en-us/library/14k9fb7t(v=vs.110).aspx Uma string que contém os endereços dos destinatários da mensagem de e-mail. É plural para "endereços" e "destinatários".
Areks,
1
Definitivamente um recurso, mas a documentação é esparsa ou inexistente. Eu tive que passar por cerca de 5 chamadas de método apenas para obter a primeira dica de que é verdade. referênciasource.microsoft.com
System
1

De acordo com a documentação:

Propriedade MailMessage.To - Retorna MailAddressCollection que contém a lista de destinatários desta mensagem de e-mail

Aqui MailAddressCollection tem um método embutido chamado

   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 (",").     

Portanto, requisito no caso de vários destinatários: Passe uma string que contém endereços de e-mail separados por vírgula

No seu caso :

simplesmente substitua todos os; com,

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

Para referência :

  1. https://docs.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
fonte
-4

Eu testei isso usando o seguinte script do PowerShell e usando (,) entre os endereços. Funcionou para mim!

$EmailFrom = "<[email protected]>";
$EmailPassword = "<password>";
$EmailTo = "<[email protected]>,<[email protected]>";
$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);
Heitor Marcos
fonte
4
Essa é uma pergunta marcada C#, não relacionada ao PowerShell de forma alguma
Jérôme MEVEL
A mesma biblioteca no final. É apenas mais fácil testar usando o PowerShell em uma máquina sem vs.. Depois de fazer o script PowerCell funcionar, é apenas uma questão de "tradução" para o equivalente em c #.
Heitor Marcos
1
Esta questão não está nem marcada, .NET Frameworkmas apenas C#. Se todos estivessem fazendo o mesmo que você, também teríamos respostas em VB.NET, F # ou mesmo C ++ para todas as questões relacionadas ao .NET Framework. Afinal é o mesmo Framework, é só uma questão de tradução ... Você entende o que quero dizer aqui? StackOverflow se tornaria uma fonte de informação realmente lixo
Jérôme MEVEL