I have an ssis package where i try to send email to a list of users via a script task.
I am able to successfully send mail to 1000 users but i get error for 10 of them. I am trying to debug the issue . The email ids does not have any problem though. Please find the code snippet below. Any pointers would be greatly helpful.
private void SendMailMessage(string SendTo, string SendCC, string SendBCC, string From, string Subject, string Body, bool IsBodyHtml, string Server, string FileAttachment)
//private void SendMailMessage(string SendTo, string From, string Subject, string Body, bool IsBodyHtml, string Server)
{
SmtpClient mySmtpClient;
String[] splittedAddresses;
MailMessage htmlMessage;
StringBuilder sbAddresses = new StringBuilder();
//emails in a batch.
int numberOfEmails = 10;
int totalEmails = 0;
//take all the addressess and append them into one whole object.
if (!String.IsNullOrEmpty(SendTo))
{
sbAddresses.Append(SendTo);
}
if (!String.IsNullOrEmpty(SendCC))
{
if (sbAddresses.Length > 0)
{
sbAddresses.Append(String.Format(",{0}", SendCC));
}
else
{
sbAddresses.Append(SendCC);
}
}
if(!String.IsNullOrEmpty(SendBCC))
{
if (sbAddresses.Length > 0)
{
sbAddresses.Append(String.Format(",{0}", SendBCC));
}
else
{
sbAddresses.Append(SendBCC);
}
}
mySmtpClient = new SmtpClient(Server);
splittedAddresses = sbAddresses.ToString().Split(new char [] {','}, StringSplitOptions.RemoveEmptyEntries);
//Send the email in batches of #numberOfEmails
while (totalEmails < splittedAddresses.Length)
{
IEnumerable<String> emailRecipients = splittedAddresses.Skip(totalEmails).Take(numberOfEmails);
CreateMailMessage(From, Subject, Body, IsBodyHtml, FileAttachment, out htmlMessage);
foreach(string email in emailRecipients)
{
htmlMessage.Bcc.Add(new MailAddress(email));
}
mySmtpClient.Send(htmlMessage);
totalEmails += emailRecipients.Count();
}
//mySmtpClient.Credentials = CredentialCache.DefaultNetworkCredentials;
}
private static void CreateMailMessage(string From, string Subject, string Body, bool IsBodyHtml, string FileAttachment, out MailMessage htmlMessage)
{
htmlMessage = new MailMessage();
htmlMessage.From = new MailAddress(From);
htmlMessage.Subject = Subject;
htmlMessage.Body = Body;
htmlMessage.IsBodyHtml = IsBodyHtml;
htmlMessage.Attachments.Add(new Attachment(FileAttachment));
}
Related
I have an SSIS package which contains Script task component. The SCR sends an email when it finds any new tags in the Database. The package is working when running through SSIS. When I deployed it in SSISDB it is running everyday and it is successful sometimes. But sometimes the job is failing throwing a error as SCR - Send an email Error. Syntax error,.....
When I tried to run it multiple times individually through job its working sometimes and failing sometimes. I don't know why it's behaving strangely.
public void Main()
{
// TODO: Add your code here
//User::varEmailMessage,User::varMail_Body,User::varMail_Subject,User::varSendMailCC,User::varSendMailFrom,
//User::varSendMailTo,$Package::strMailHost,$Package::strMailPassWord,$Package::strMailUserName
string MailTo = Dts.Variables["User::varSendMailTo"].Value.ToString();
string MailFrom = Dts.Variables["User::varSendMailFrom"].Value.ToString();
string MailCC = Dts.Variables["User::varSendMailCC"].Value.ToString();
string EmailMessage = Dts.Variables["User::varEmailMessage"].Value.ToString();
string MailBody = string.Empty;
//string MailSub = string.Empty;
MailBody = #" " + EmailMessage ;
EmailFunction(MailTo, MailBody, MailCC);
Dts.TaskResult = (int)ScriptResults.Success;
}
public void EmailFunction(string MailTo, string MailBody, string MailCC)
{
string username = Dts.Variables["$Package::strMailUserName"].Value.ToString();
string password = Dts.Variables["$Package::strMailPassWord"].Value.ToString();
string MailSub = "Production Missing Tags List for " + DateTime.Now.ToString("dd-MMM-yyyy");
string EmailTo = MailTo;
string body = MailBody;
SendEmail(username, password, EmailTo, MailSub, body, MailCC);
}
public void SendEmail(string username, string password, string EmailTo, string MailSub, string MailBod, string EmCC)
{
try
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress(username);
mail.Subject = MailSub;
mail.Body = MailBod;
mail.IsBodyHtml = true;
if (EmailTo != "")
{
if (EmailTo.Contains(";"))
{
string[] toList = EmailTo.Split(';');
foreach (string EmailAddress in toList)
{
if (EmailAddress != "")
{
mail.To.Add(EmailAddress);
}
}
}
else
{
mail.To.Add(EmailTo);
}
}
if (EmCC != "")
{
if (EmCC.Contains(";"))
{
string[] ccList = EmCC.Split(';');
foreach (string EmailAddress in ccList)
{
if (EmailAddress != "")
{
mail.CC.Add(EmailAddress);
}
}
}
else
{
mail.CC.Add(EmCC);
}
}
var client = new SmtpClient(Dts.Variables["$Package::strMailHost"].Value.ToString(), 587)
{
UseDefaultCredentials=false,
Credentials=new NetworkCredential(username,password),
EnableSsl=true
};
client.Send(mail);
}
catch(Exception ex)
{
//MessageBox.Show(ex.Message.ToString());
Dts.Events.FireError(-1, "Main()", ex.Message, "", -1); // Raise the error event to SSIS,
Dts.TaskResult = (int)ScriptResults.Failure; // and report the task failed.
}
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
I'm trying to remove or exclude a couple specific e-mail addresses from the CC e-mail address list. How should I do this? Here is the function:
private void SendEmail(string emailTo, string subject, string body)
{
using (SmtpClient client = new SmtpClient(System.Configuration.ConfigurationManager.AppSettings["SmtpServerAddress"]))
{
MailMessage email = new MailMessage();
email.From = new MailAddress(GetUserEmail());
string emailCc = ConfigurationManager.AppSettings["EmailCc"];
foreach (var item in emailTo.Split(';'))
{
email.To.Add(new MailAddress(item.Trim()));
}
foreach (var item in emailCc.Split(';'))
{
email.CC.Add(new MailAddress(item.Trim()));
}
email.Subject = subject;
email.IsBodyHtml = true;
email.Body = body;
return;
}
}
You put the emails you don't want into an array:
var badEmails = new [] { "a#a.aa", "b#b.bb" }
Then you use LINQ to remove them from the split:
var ccList = emailCc.Split(';').Where(cc => !badEmails.Any(b => cc.IndexOf(b, System.StringComparison.InvariantCultureIgnoreCase) > -1));
Then you add those in ccList to your email
You can try with this if you know email:
foreach (var item in emailCc.Split(';'))
{
if (!new string[] { "bad#gmail.com", "uncle#sam.com", "stack#overflow.com"}.Contains(email))
{
email.CC.Add(new MailAddress(item.Trim()));
}
}
instead of if statement you can use regular expression if you want to exclude some email with specific pattern.
I have to send notification to a array of users in the to-recipients and each user has a different message body which is stored in another array.
When i try to use multiple calls to SMTP.send() to send the notification to each user (i tried testing for 2 users) one by one with their respective message body, I get Exception like
"{"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 10.1.11.16:25"}".
where as it works fine in the case when make a single SMTP.send call where i have ';' separated recipients and same message body.
How do I Solve it.
Controller code sending the array of users and message in array.
string[] emailBodyList = FormatedEmail.ToArray();
string[] emailIdList = emailIDs.ToArray(); DMS.Common.Encyptor.NotificationSend(FromEmail, ToEmail, CCEmail, BCCEmail, model.MailSubject, emailBodyList, emailIdList);
In the Encryptor.cs the SMTP method:
public static void NotificationSend(string FromEmail, string ToEmail, string CCEmail, string BCCEmail, string EmailSubject, string[] EmailBody = null, string[] emailID =null)
{
for(int i = 0; i < EmailBody.Length ; i++)
{
string notificationBody = EmailBody[i];
string notificationTo = emailID[i];
EmailSend(FromEmail, notificationTo, null, null, EmailSubject, notificationBody);
}
}
public static void EmailSend(string FromEmail, string ToEmail, string CCEmail, string BCCEmail, string EmailSubject, string EmailBody= null, string emailID = null)
{
var email = new MailMessage();
email.From = new MailAddress(FromEmail);
string[] toemails = ToEmail.Split(';');
foreach (string str in toemails)
{
if (!String.IsNullOrEmpty(str) && str.Contains('#'))
{
email.To.Add(new MailAddress(str.TrimEnd(new char[] { ',' })));
}
}
//email.Headers.Add("Reply-To", "saeed.badar#unibetonrm.com");
// Add CC
if (!String.IsNullOrEmpty(CCEmail))
{
string[] ccemails = CCEmail.Split(';');
foreach (string str in ccemails)
{
if (!String.IsNullOrEmpty(str) && str.Contains('#'))
{
email.CC.Add(new MailAddress(str.TrimEnd(new char[] { ',' })));
}
}
}
// Add BCC
if (!String.IsNullOrEmpty(BCCEmail))
{
string[] bccemails = BCCEmail.Split(';');
foreach (string str in bccemails)
{
if (!String.IsNullOrEmpty(str) && str.Contains('#'))
{
email.Bcc.Add(new MailAddress(str.TrimEnd(new char[] { ',' })));
}
}
}
email.IsBodyHtml = true;
email.Body = EmailBody;
email.Subject = EmailSubject;
SmtpClient smtpClient = new SmtpClient();
smtpClient.Host = AppConfig.GetValue("SmtpHost").ToString();
smtpClient.Port = int.Parse(AppConfig.GetValue("SmtpPort").ToString());
//smtpClient.EnableSsl = true;
smtpClient.Credentials = CredentialCache.DefaultNetworkCredentials;
smtpClient.Credentials = new System.Net.NetworkCredential(AppConfig.GetValue("SmtpServerUserName").ToString(), AppConfig.GetValue("SmtpServerPassword").ToString());
smtpClient.Send(email);
}
The error message seems to be saying that the error has nothing to do with the type of emails you are trying to send.
Does your SMTP need your windows credentials to log you in? You seem to be trying to do both. Since you are specifying a username and password, try setting
smtpClient.UseDefaultCredentials = false;
before
smtpClient.Credentials = new System.Net.NetworkCredential(AppConfig.GetValue("SmtpServerUserName").ToString(), AppConfig.GetValue("SmtpServerPassword").ToString());
Also, you need to decide whether you are going to use CredentialCache.DefaultNetworkCredentials or not.
Make sure your firewall isn't blocking the connection to the SMTP server, and that your credentials are correct.
I have a system that sends emails with inline pictures. The problem is how Outlook 2013 displays the attachments. Can I update my code in a way that tells outlook not to display the paperclip icon seen here?
The idea is that I only want to display this icon when full sized pictures are attached. Not inline attachments.
Here's the code that generates the email. Create a basic console app, specify your To / mailserver / picture path, and run.
static void Main(string[] args)
{
Console.WriteLine("Prepping email message....");
var subject = "Test Subject With Inline";
var message = "<p>This is a test message.</p><br/><br/><p>[CompanyLogo]</p>";
var to = new List<string>();
to.Add("My.Name#company.com");
Console.WriteLine("Sending email message....");
if (SendMessageToFrom(subject, message, to, new List<string>()))
{
Console.WriteLine("Email sent! Check your inbox.");
}
else
{
Console.WriteLine("Error sending email!");
}
}
public static bool SendMessageToFrom(String subject, String message, List<String> to, List<String> cc)
{
try
{
// Construct the email
var sendMessage = new MailMessage()
{
IsBodyHtml = true,
From = new MailAddress("noreply#company.com"),
Subject = subject,
Body = message
};
if (sendMessage.Body.Contains("[CompanyLogo]"))
{
sendMessage.AlternateViews.Add(EmbedLogo(sendMessage.Body));
}
// Add the list of recipients
foreach (var recipient in to)
{
sendMessage.To.Add(recipient);
}
foreach (var recipient in cc)
{
sendMessage.CC.Add(recipient);
}
//Specify the SMTP server
var smtpServerName = "mailserver.company.com";
var mailClient = new SmtpClient(smtpServerName);
mailClient.Send(sendMessage);
return true;
}
catch
{
throw;
}
}
private static AlternateView EmbedLogo(string html)
{
var inline = new LinkedResource("img\\company-logo.jpg");
inline.ContentId = Guid.NewGuid().ToString();
html = html.Replace("[CompanyLogo]", string.Format(#"<img src='cid:{0}'/>", inline.ContentId));
var result = AlternateView.CreateAlternateViewFromString(html, null, System.Net.Mime.MediaTypeNames.Text.Html);
result.LinkedResources.Add(inline);
return result;
}
Update: Here's the code that did the trick:
private static MailMessage EmbedLogo(MailMessage mail)
{
var inline = new Attachment("img\\company-logo.jpg");
inline.ContentId = Guid.NewGuid().ToString();
inline.ContentDisposition.Inline = true;
inline.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
mail.Body = mail.Body.Replace("[CompanyLogo]", string.Format(#"<img src='cid:{0}'/>", inline.ContentId));
mail.Attachments.Add(inline);
return mail;
}
And I also updated the main method to this:
if (sendMessage.Body.Contains("[CompanyLogo]"))
{
sendMessage = EmbedLogo(sendMessage);
}
Make sure your attachments have the Content-ID MIME header and the message's HTML body refers to them using the cid attribute : <img src="cid:xyz"> (where xyz is the value of the Content-ID MIME header).
I have developed on Windows Application. Now i need to send an email (attachment feature included) by Web Service. How can i do that?
Also i need to notify the email before 'n' days. ('n' days is a feature controlled by user)
Let me know if any comment.
Thanks.
public bool Send(string toAddress, string subject, string body, bool isHtml, List<string> files)
{
try
{
MailMessage mailMsg = new MailMessage();
mailMsg.To = toAddress;
mailMsg.Headers.Add("From", string.Format("{0} <{1}>", senderName, senderAddress));
mailMsg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"] = server;
mailMsg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"] = port;
mailMsg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"] = 2;
if (enableAuth)
{
mailMsg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"] = 1;
mailMsg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusername"] = userName;
mailMsg.Fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"] = password;
}
if (enableSsl)
{
mailMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", "true");
}
if (isHtml)
{
mailMsg.BodyFormat = MailFormat.Html;
}
mailMsg.BodyEncoding = Encoding.UTF8;
mailMsg.Subject = subject;
mailMsg.Body = body;
for (int i = 0; i < files.Count; i++)
{
mailMsg.Attachments.Add(new MailAttachment(files[i]));
}
SmtpMail.SmtpServer = server;
SmtpMail.Send(mailMsg);
return true;
}
catch (Exception ex)
{
this.errorMsg = ex.Message;
return false;
}
}
Note that you must use System.Web.Mail for this cod to work.