Надіслати електронну пошту кільком одержувачам за допомогою MailMessage?


85

У мене кілька одержувачів електронної пошти, що зберігаються в SQL Server. Коли я натискаю кнопку відправити на веб-сторінці, вона повинна надіслати електронне повідомлення всім одержувачам. Я розділив електронні листи за допомогою ;.

Далі наводиться єдиний код одержувача.

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();

Що ви пробували дотепер? У вас це працює для одного одержувача?
— Brendan Green

@BrendanGreen так, я працюю на одного одержувача.
— Четан Гоєнка

5
Крім того, FYI, ваші MailMessageта SmtpClientекземпляри повинні бути в usingблоках.
— Джон Сондерс,

2
@JohnSaunders Вони повинні, але, безумовно, не потребують .
— Num Lock

1
@JohnSaunders Перш за все, ваше формулювання дуже вводить в оману: ви, напевно, сперечаєтесь з цього приводу, але "потрібно бути в usingблоках" не рівно "потрібно утилізувати". По-друге, у виробничому коді, як веб-додатки, ви, як правило, хочете використовувати його в SendAsyncбудь-якому випадку, який працює за призначенням без необхідності утилізації SnmpClientекземпляра.
— Num Lock

Відповіді:


178

Легко!

Просто розділіть список вхідних адрес на ";" символу та додайте їх до поштового повідомлення:

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

У цьому прикладі addressesмістить " address1@example.com;address2@example.com".


56
Я запізнююсь на вечірку, але конструктор MailMessage (рядок від, рядок до) приймає список адрес, розділених комами. Отже, ви могли зробити щось на зразок нового MailMessage (fromMail, adrese.replace (";", ",")) Можливо, не краще використовувати заміну, але я вважаю, що мені слід прокоментувати це на випадок, якщо інші люди вже розділили комами струни! Тоді не було б потреби в розбитті або заміні.
— Арекс

@Areks, якщо ти можеш скласти рядок зразка коду, подібного до Брендана, ти обов'язково повинен додати це як відповідь.
— Адам Міллер,

@Areks дякую за цей коментар, я вже розділяв адреси, поки не прочитав ваш коментар. це саме те, що я хочу!
— Djeroen

Це необхідно? Ви не просто берете вже відформатований рядок для кількох адрес і розділяєте їх, а потім перепризначаєте? Якщо ви надсилаєте To () рядок, згаданий To ("a1; a2; a3"), чому вам потрібно розділити їх, а потім призначити окремо? Оскільки він не включає декілька адрес у AddressCollection або рядок-роздільник.
— Кейсі

82

Як запропонував Адам Міллер у коментарях, я додаю ще одне рішення.

Конструктор MailMessage (String from, String to) приймає список адрес, відокремлених комами. Отже, якщо у вас вже є список, відокремлений комами (','), використання настільки просто, як:

MailMessage Msg = new MailMessage(fromMail, addresses);

У цьому конкретному випадку ми можемо замінити ';' для ',' і все ще використовуйте конструктор.

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

Чи віддаєте ви перевагу цій чи прийнятій відповіді, вирішувати вам. Можна стверджувати, що цикл робить намір чіткішим, але він коротший і не тьмяний. Але якщо у вас вже є список, відокремлений комами, я думаю, що це шлях.


2
Оскільки це спричинило проблему з керованою мною програмою, яка реалізувала це, слід перевірити, чи кінцевий символ є двокрапкою, і видалити його перед запуском команди replace. Я не впевнений, чи кінцева крапка з комою вважається дійсним списком одержувачів, але люди можуть звикнути бачити кінцеву крапку з комою через такі програми, як Outlook. У списку, відокремленому комами, який ви передаєте MailMessage, у вас не може бути кінцевої коми.
— Девід Якобсен,

1
На моє розуміння, не повинно бути кінцевої коми / крапки з комою, якщо після цього нічого немає ... Але, безумовно, хороший коментар, тому люди, які читають це, знають про це. Дякую!
— Арекс

1
Це десь задокументовано? Документи конструктора просто описують toпараметр як "Рядок, що містить адресу одержувача повідомлення електронної пошти". Я хочу використовувати його, але не якщо його підтримку можна буде видалити.
— xr280xr

1
На жаль, формат, здається, не задокументований, але конструктор стверджує, що він може бути для кількох одержувачів: msdn.microsoft.com/en-us/library/14k9fb7t(v=vs.110).aspx Рядок, що містить адреси одержувачів електронного повідомлення. Це множина для "адрес" і "одержувачів".
— Арекс

1
Безумовно, особливість, але документація є мізерною або її взагалі немає. Мені довелося пройти близько 5 викликів методів лише для того, щоб отримати перший натяк на те, що це правда. referenceource.microsoft.com/#System/net/System/Net/mail/…
— Sinjai

1

Відповідно до документації:

Властивість MailMessage.To - повертає MailAddressCollection, що містить список одержувачів цього повідомлення електронної пошти

Тут MailAddressCollection має вбудований метод, який називається

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

Тому вимога у випадку кількох одержувачів: Передайте рядок, що містить адреси електронної пошти, розділені комами

У вашому випадку:

просто замінити всі; з,

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

Для довідки:

  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/

-4

Я перевірив це, використовуючи такий сценарій PowerShell та використовуючи (,) між адресами. У мене це вийшло!

$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
Це питання з тегами C#, взагалі не пов’язане з PowerShell
— Jérôme MEVEL

Зрештою та сама бібліотека. Це просто простіше протестувати за допомогою PowerShell на машині, де немає проти. Після того, як сценарій Powersell запрацює, це просто питання "перекладу" на еквівалент c #
— Heitor Marcos

1
Це питання навіть не позначено тегами, .NET Frameworkа лише C#. Якби всі робили те саме, що і ви, ми також мали б відповіді на всі питання, пов’язані з VB.NET, F # або навіть C ++ .NET Framework. Зрештою, це одна і та ж структура, справа лише в перекладі ... Ви бачите мій сенс тут? StackOverflow стане справді сміттєвим джерелом інформації
— Jérôme MEVEL
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.