C# MVC Send email to multiple recipient - c#

I have trying to send one mail to Test1 and Test2. I tried separating the recipients with ; like To ="Test1#stanleytests.co.za;Test2#stanleytests.co.za" that did not work and also tried concatenating them by doing To="Test1#stanleytests.co.za"+"Test2#stanleytests.co.za" that did not work. now I wrote and Array. the thing with my array is that it sends 2 mails, so i only want to sent one mail to two recipient.
private void SendDailyEmails(DateTime today)
{
today = DateTime.Now;
string recipient = "Test1#stanleytests.co.za,Test2#stanleytests.co.za";
string[] emailTo = recipient.Split(',');
for (int i = 0; i < emailTo.GetLength(0); i++)
{
var emailObject = new EmailObject
{
To = emailTo[i],
Cc = "me#stanleytests.co.za",
Subject = "Daily Mail",
Body = "Good morning, <br/><br/> This email is sent to you: <strong> "please be adviced" </strong> <br/><br/>Regards"
};
_emailService.SendEmail(emailObject);
}
}
Please assist here.thanks

Partially your code, see the example below. Honestly, I don't have access to our SMTP servers here, so, I can't really test it. This should set you on the right path. I am guessing your issue really is that you are missing: new MailAddress(i) .
Hope this helps, there are more reference material on MSDN's site.
private void SendDailyEmails()
{
var today = DateTime.Now;
var recipient = "Test1#stanleytests.co.za,Test2 #stanleytests.co.za";
var message = new MailMessage()
{
From = new MailAddress("Somebody"),
CC = { new MailAddress("me#stanleytests.co.za") },
Subject = "Daily Mail",
Body = #"Good morning, <br/><br/> This email is sent to you: <strong> ""please be adviced"" </strong> <br/><br/>Regards",
IsBodyHtml = true
};
foreach (var i in recipient.Split(',').ToList())
{
message.To.Add(new MailAddress(i));
}
// do your "_emailService.SendEmail(message);
}

We don't know what library you are using for sending emails thus I can only make suggestions.
The convention for joining several email address is to separate them with ; :
emailObject.To = String.Join(";", recipient.Split(','));

string body = "Body of email";
var message = new MailMessage();
message.To.Add(new MailAddress("example#exaple.com"));
message.To.Add(new MailAddress("example2#exaple.com"));
message.From = new MailAddress("example#gmail.com", "Name");
message.Subject = "This is the subject";
message.Body = body;
message.IsBodyHtml = true;

Related

C# MailMessage BCC property show address list in email when delivery

When i used this code, when the email is delivered the list of addresses in bcc is visible, why please?
I use .Net Framework 4.6.2
The code works correctly, it sends the emails but when I check the To: in the email delivered I can see all the recipients that I have included in .Bcc.Add
bcc does not work as microsoft says?
public static bool SendEmails(string[] emailList, string from, string body, string subject, string attachment)
{
var result= false;
MailMessage email = null;
if (emailList!= null && !string.IsNullOrWhiteSpace(from))
{
email = new MailMessage
{
Priority = MailPriority.High,
From = new MailAddress(from),
Subject = subject,
Body = body,
BodyEncoding = Encoding.UTF8,
IsBodyHtml = true,
DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure,
};
if (!string.IsNullOrWhiteSpace(attachment))
{
email.Attachments.Add(new Attachment(attachment));
}
var smtp = new SmtpClient
{
Host = host,
Credentials =new System.Net.NetworkCredential("user","pass"),
EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["enablessl"]),
Port = int.Parse(ConfigurationManager.AppSettings["port"])
};
if (emailList.Count() > 0)
{
foreach (string email in emailList)
{
email.Bcc.Add(new MailAddress(email));
}
}
smtp.Send(email);
result= true;
}
return restul;
}
Apparently, it is necessary to include an email in emai.To.Add("anymail#anyhost.com") before starting the loop where the addresses are loaded in bcc, I don't know if this has any other consequences, but that's how it works. Email addresses are no longer displayed in the To: of the delivered message.

c# send mail to multiple recipients

I use this to send mails, I've defined some package variables which contains values:
public MailProperties(ScriptObjectModel dts)
{
if (
!string.IsNullOrEmpty((string)dts.Variables["$Package::mailFrom"].Value) &&
!string.IsNullOrEmpty((string)dts.Variables["$Package::mailTo"].Value) &&
!string.IsNullOrEmpty((string)dts.Variables["$Package::mailPwd"].GetSensitiveValue()) &&
!string.IsNullOrEmpty((string)dts.Variables["$Package::mailSmtp"].Value) &&
!string.IsNullOrEmpty((string)dts.Variables["$Package::mailPort"].Value)
)
{
fromMail = (string)dts.Variables["$Package::mailFrom"].Value;
toMail = (string)dts.Variables["$Package::mailTo"].Value;
bccMail = (string)dts.Variables["$Package::mailBcc"].Value;
accountPassword = (string)dts.Variables["$Package::mailPwd"].GetSensitiveValue();
accountSmtp = (string)dts.Variables["$Package::mailSmtp"].Value;
accountSmtpPort = (string)dts.Variables["$Package::mailPort"].Value;
useSSL = (bool)dts.Variables["$Package::useSSL"].Value;
pathAttachment = new List<string>();
pathAttachment.Add((string)dts.Variables["User::pathFileReject"].Value);
pathAttachment.Add((string)dts.Variables["User::pathFileReject2"].Value);
}
else
{
throw new Exception("error text...");
}
}
I need to send mail to more people, so I set mailTo with mail1#gmail.com, mailBcc as mail2#gmail.com and it works, but if I set mailBcc as "mail2#gmail.com, mail3#gmail.com" or "mail2#gmail.com; mail3#gmail.com" it doesn't work, how I can do that?
EDIT: this is the sendMail function
public static void sendMail(MailProperties mailProperties, ReportETL reportETL)
{
MimeMessage message = new MimeMessage();
message.From.Add(new MailboxAddress("text..", mailProperties.fromMail));
message.To.Add(new MailboxAddress(mailProperties.toMail));
message.Subject = "text...";
if (!string.IsNullOrEmpty(mailProperties.bccMail))
{
message.Bcc.Add(new MailboxAddress(mailProperties.bccMail));
}
BodyBuilder bodyBuilder = new BodyBuilder();
bodyBuilder.HtmlBody = ReportETLService.getHtmlFromReporETL(reportETL);
mailProperties.pathAttachment.Where(x => File.Exists(x)).ToList().ForEach(y => bodyBuilder.Attachments.Add(y));
message.Body = bodyBuilder.ToMessageBody();
try
{
SmtpClient smtpClient = new SmtpClient();
smtpClient.Connect(mailProperties.accountSmtp, int.Parse(mailProperties.accountSmtpPort), mailProperties.useSSL);
smtpClient.Authenticate(mailProperties.fromMail, mailProperties.accountPassword);
smtpClient.Send(message);
smtpClient.Disconnect(true);
}
catch (Exception e) { throw new Exception("text... " + e.Message); }
}
according to documentation message.To is list type.So you can add more adress like this.
InternetAddressList list = new InternetAddressList();
list.add(adress1)
list.add(adress2)
list.add(adress3)
list.add(adress4)
message.To.AddRange(list);
Instead of using BCC (which would be an option, but has the problem of max count) just iterate over all mail addresses and send one for each recipient. (Not to fast or you get other problems)
This way it should be "easier" to spot mails that will not get delivered.
Well, assuming that your toMail, ccMail, and bccMail properties are just strings and not lists of strings, you could do something like this:
InternetAddressList list;
if (!string.IsNullOrEmpty(mailProperties.toMail) && InternetAddressList.TryParse (mailProperties.toMail, out list))
message.To.AddRange(list);
if (!string.IsNullOrEmpty(mailProperties.ccMail) && InternetAddressList.TryParse (mailProperties.ccMail, out list))
message.Cc.AddRange(list);
if (!string.IsNullOrEmpty(mailProperties.bccMail) && InternetAddressList.TryParse (mailProperties.bccMail, out list))
message.Bcc.AddRange(list);

Send mail stored in a variable

I have a simple table(MyEmail) in SQL with some emails that need to be sent, for example:
ID Email
1 name#yahoo.com
2 something2#yahoo.com
3 name3#google.com
4 something4#yahoo.com
I made a stored procedure(GetAddress) to collect them so I can later store them into a variable:
SELECT Email
FROM dbo.MyEmai
I need help with the C# part of the code:
var MyEmails = new List<Email>();
SqlCommand cmdEmails = new SqlCommand("GetAddress", connection);
SqlDataReader rdEmails = cmdEmails.ExecuteReader();
while (rdEmails.Read())
{
MyEmails.Add(new Email() { MyEmails = rdEmails[0].ToString() }); // as an example
}
This code returns list but emails are located bellow WebApplication.MyPage.
Email names.
MyEmails return :
WebApplication.MyPage.Email > name#yahoo.com
WebApplication.MyPage.Email > something2#yahoo.com ...
And I need this WebApplication.MyPage.Email removed so only emails will be shown as strings first.
Code that sends emails:
SmtpClient client = new SmtpClient();
client.Port = 112;
client.Host = "my-smtp";
client.Timeout = 10000;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("myEmail#provider.com", "");
MailMessage mm = new MailMessage(LocalName, LocalName + MyEmails, "New Mail subject", "This is Email body !");
client.Send(mm);
So because of this MyEmails has an error : Error 24 Argument 2: cannot convert from 'System.Collections.Generic.List' to 'string'
Can someone help me with this?
Thanks in advance!
The MailMessage class from .Net does not accepts a List as a valid parameter. Iiterate over your collection creating multiple mailmessage.
The code should look something like this
foreach (var emailadressObject in myEmails)
{
// get your emailadres string from your object..
// Bit confusion using a collection MyEmails and a Property in you mail objetc with MyEmails
var emailadresstring = emailadressObject.MyEmails;
var message = new MailMessage("from#me.com", emailadresstring, "New Mail subject", "This is Email body !");
// Do you magic with the mail message
}

C# email alert not picking up new code

I have following code for sending an email alert to around 60 users when an extract gets uploaded. However something strange is happening, it is sending to the previous query results not the new ones. The only difference is the quantity of users before it was sending to only a few people now its sending to a larger quantity. But on the code with larger quantity the application seems to not see that it has changed and sends to previous users. Like its cached the query or something. I don't know whats going on. But when I do change it to just one email address it works fine and picks up changes.
if (Session["ExtractNo"].ToString() == "Extract 1")
{
//Connection String (SendEmail)
string SendEmail = ConfigurationManager.ConnectionStrings["SendEmail"].ConnectionString;
SqlDataReader reader;
String SendMessage = "SELECT Name, Position, Email FROM AuthorisedStaff Where Position = 'CM' or Position = 'DHOD' or Position = 'HOD'"; //<---- change position before launch
using (SqlConnection myConnection = new SqlConnection(SendEmail))
{
myConnection.Open();
SqlCommand myCommand = new SqlCommand(SendMessage, myConnection);
ArrayList emailArray = new ArrayList();
reader = myCommand.ExecuteReader();
var emails = new List<EmailCode>();
while (reader.Read())
{
emails.Add(new EmailCode
{
Email = Convert.ToString(reader["Email"]),
Name = Convert.ToString(reader["Name"]),
Position = Convert.ToString(reader["Position"])
});
}
foreach (EmailCode email in emails)
{
//Email Config
const string username = "roll#test.co.uk"; //account address
const string password = "######"; //account password
SmtpClient smtpclient = new SmtpClient();
MailMessage mail = new MailMessage();
MailAddress fromaddress = new MailAddress("roll#test.co.uk", "PTLP"); //address and from name
smtpclient.Host = "omavex11"; //host name for particular email address
smtpclient.Port = 25; //port number for particular email address
mail.From = fromaddress;
mail.To.Add(email.Email);
mail.Subject = ("PTLP Check");
mail.IsBodyHtml = true;
//change context of message below as appropriate
mail.Body = HttpUtility.HtmlEncode(email.Name) + " <br /> <p>Part Time Lecturer Payroll details are now available for checking. If any changes need made please notify MIS as soon as possible. </p> <p>Please ensure all Adjustments have also been submitted. All Adjustments not submitted on time will be paid the following month. </p> ";
//smtpclient.EnableSsl = true;
smtpclient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpclient.Credentials = new System.Net.NetworkCredential(username, password);
smtpclient.Send(mail);
}
}
}
Try clearing the list first before adding new items/objects
I assume that this
var emails = new List<EmailCode>();
is the list.

How to Add Custom variables to SendGrid email via API C# and Template

I am trying to figure out how to add variables to existing template (example: Web Link Or Name dynamically) which has been created in sendgrid template engine, I am unsure how to do this using the SendGrid C# .NET libraries. I am wondering if anyone could help me.
// Create the email object first, then add the properties.
SendGridMessage myMessage = new SendGridMessage();
myMessage.AddTo("test#test.com");
myMessage.From = new MailAddress("test#test.com", "Mr test");
myMessage.Subject = " ";
var timestamp = DateTime.Now.ToString("HH:mm:ss tt");
myMessage.Html = "<p></p> ";
myMessage.EnableTemplate("<p> <% body %> Hello</p>");
myMessage.EnableTemplateEngine("9386b483-8ad4-48c2-9ee3-afc7618eb56a");
var identifiers = new Dictionary<String, String>();
identifiers["USER_FULLNAME"] = "Jimbo Jones";
identifiers["VERIFICATION_URL"] = "www.google.com";
myMessage.AddUniqueArgs(identifiers);
// Create credentials, specifying your user name and password.
var credentials = new NetworkCredential("username", "password");
// Create an Web transport for sending email.
var transportWeb = new Web(credentials);
// Send the email.
transportWeb.Deliver(myMessage);
My Email
Hello -REP-
<%body%>
Fotter
My C# Code
myMessage.AddSubstitution("-REP-", substitutionValues);
Works PERFECT!!!
I found the solution:
replacementKey = "*|VERIFICATION_URL|*";
substitutionValues = new List<string> { VERIFICATION_URL };
myMessage.AddSubstitution(replacementKey, substitutionValues);
I've used the following approach. Note you have to provide the mail.Text and mail.Html values - I use the empty string and <p></p> tag as seen in the example. Your SendGrid template also still must contain the default <%body%> and <%subject%> tokens, although they will be replaced with the actual subject and body value specified in the mail.Text and mail.Html properties.
public void Send(string from, string to, string subject, IDictionary<string, string> replacementTokens, string templateId)
{
var mail = new SendGridMessage
{
From = new MailAddress(from)
};
mail.AddTo(to);
mail.Subject = subject;
// NOTE: Text/Html and EnableTemplate HTML are not really used if a TemplateId is specified
mail.Text = string.Empty;
mail.Html = "<p></p>";
mail.EnableTemplate("<%body%>");
mail.EnableTemplateEngine(templateId);
// Add each replacement token
foreach (var key in replacementTokens.Keys)
{
mail.AddSubstitution(
key,
new List<string>
{
replacementTokens[key]
});
}
var transportWeb = new Web("THE_AUTH_KEY");
var result = transportWeb.DeliverAsync(mail);
}
It can then be called like this:
Send(
"noreply#example.com",
"TO_ADDRESS",
"THE SUBJECT",
new Dictionary<string, string> {
{ "#Param1!", "Parameter 1" },
{ "#Param2!", "Parameter 2" } },
"TEMPLATE_GUID");
After did lots of RND. My below code is working fine & Tested as well.
SendGridMessage myMessage = new SendGridMessage();
myMessage.AddTo(email);
myMessage.AddBcc("MyEmail#gmail.com");
myMessage.AddBcc("EmailSender_CC#outlook.com");
myMessage.From = new MailAddress("SenderEmail#outlook.com", "DriverPickup");
//myMessage.Subject = "Email Template Test 15.";
myMessage.Headers.Add("X-SMTPAPI", GetMessageHeaderForWelcome("MyEmail#Gmail.com", callBackUrl));
myMessage.Html = string.Format(" ");
// Create an Web transport for sending email.
var transportWeb = new Web(SendGridApiKey);
// Send the email, which returns an awaitable task.
transportWeb.DeliverAsync(myMessage);
I have created Separate method for getting JSON header
private static string GetMessageHeaderForWelcome(string email, string callBackUrl)
{
var header = new Header();
//header.AddSubstitution("{{FirstName}}", new List<string> { "Dilip" });
//header.AddSubstitution("{{LastName}}", new List<string> { "Nikam" });
header.AddSubstitution("{{EmailID}}", new List<string> { email });
header.AddSubstitution("-VERIFICATIONURL-", new List<string>() { callBackUrl });
//header.AddSubstitution("*|VERIFICATIONURL|*", new List<string> { callBackUrl });
//header.AddSubstitution("{{VERIFICATIONURL}}", new List<string> { callBackUrl });
header.AddFilterSetting("templates", new List<string> { "enabled" }, "1");
header.AddFilterSetting("templates", new List<string> { "template_id" }, WelcomeSendGridTemplateID);
return header.JsonString();
}
Below code I have used in my HTML Sendgrid template.
<div>Your {{EmailID}} register. Please <a class="btn-primary" href="-VERIFICATIONURL-">Confirm email address</a></div>
In case if any query please let me know.
For inline HTML replace you need to use -YourKeyForReplace- & for text replace you need to use {{UserKeyForReplace}}

Categories