Script task failing sometimes when running through SSMS - c#

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
}
}

Related

Sendgrid unsubscribe preferences

I'm using Sendgrid and try to sending these emails with C# language.
So, what i'm doing is configure the SMTP and API Keys in my apps, and boom, there goes the emails were sent.
The question is, How do I insert the Unsubscribe Preferences group in my X-SMTPAPI header?
FYI, unsubscribe preferences is where you can choose which group you want to unsubscribe instead of global unsubscribe.
I already checked these links:
https://sendgrid.com/docs/API_Reference/Web_API_v3/Suppression_Management/groups.html
https://sendgrid.com/docs/API_Reference/Web_API_v3/How_To_Use_The_Web_API_v3/requests.html
https://sendgrid.com/docs/API_Reference/SMTP_API/suppressions.html
I also checked the library C# on their github.
But none of these is made me clear.
I'm completely blind with JSON, GET, REQUEST, RESPONSE and such.
this is my C# code
public void Main()
{
string sSubject = Dts.Variables["vSubject"].Value.ToString();
string sBody = Dts.Variables["vBodyMessage"].Value.ToString();
int iPriority = 2;
if (SendMail(sSubject, sBody, iPriority))
{
Dts.TaskResult = (int)ScriptResults.Success;
}
else
{
//Fails the Task
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
//THIS IS THE HEADER X-SMTPAPI, I DUNNO HOW TO USE IT :(
//I WANNA ADD MY GROUPS HERE
private static string XsmtpapiHeaderAsJson()
{
var header = new Header();
header.SetAsmGroupId(777);
//var uniqueArgs = new string[] { "Small", "Medium", "Large" };
//{
// "asm_groups_to_display": [1, 2, 3]
//};
//header.AddUniqueArgs({ "asm_groups_to_display": ['1', '2', '3']});
//var subs = new List<String> { "私はラーメンが大好き" };
//header.AddSubstitution("%tag%", subs);
//dynamic stuff = json
return header.JsonString();
}
public bool SendMail(string sSubject, string sMessage, int iPriority)
{
string xmstpapiJson = XsmtpapiHeaderAsJson();
try
{
string sEmailServer = Dts.Variables["sServer"].Value.ToString();
string sEmailPort = Dts.Variables["sPort"].Value.ToString();
string sEmailUser = Dts.Variables["sUser"].Value.ToString();
string sEmailPassword = Dts.Variables["sPassword"].Value.ToString();
string sEmailSendTo = Dts.Variables["sSendTo"].Value.ToString();
string sEmailSendToName = Dts.Variables["sSendToName"].Value.ToString();
//string sEmailSendCC = Dts.Variables["sSendCC"].Value.ToString();
string sEmailSendFrom = Dts.Variables["sFrom"].Value.ToString();
string sEmailSendFromName = Dts.Variables["sFromName"].Value.ToString();
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress(sEmailSendFrom, sEmailSendFromName);
//You can have multiple emails separated by ;
string[] sEmailTo = Regex.Split(sEmailSendTo, ";");
//string[] sEmailCC = Regex.Split(sEmailSendCC, ";");
int sEmailServerSMTP = int.Parse(sEmailPort);
smtpClient.Host = sEmailServer;
smtpClient.Port = sEmailServerSMTP;
System.Net.NetworkCredential myCredentials =
new System.Net.NetworkCredential(sEmailUser, sEmailPassword);
smtpClient.Credentials = myCredentials;
message.From = fromAddress;
//MailAddress toAddress = new MailAddress(sEmailSendTo, sEmailSendToName);
//message.To.Add(toAddress);
if (sEmailTo != null)
{
for (int i = 0; i < sEmailTo.Length; ++i)
{
if (sEmailTo[i] != null && sEmailTo[i] != "")
{
MailAddress toAddress = new MailAddress(sEmailTo[i], sEmailSendToName);
message.To.Add(toAddress);
}
}
}
switch (iPriority)
{
case 1:
message.Priority = MailPriority.High;
break;
case 3:
message.Priority = MailPriority.Low;
break;
default:
message.Priority = MailPriority.Normal;
break;
}
//message.Headers.Add("X-SMTPAPI", xmstpapiJson);
//smtpClient.SendCompleted += SendCompletedCallback;
//const string state = "test1";
message.Subject = sSubject;
message.IsBodyHtml = true;
message.Body = sMessage;
//smtpClient.SendAsync(message, state);
smtpClient.Send(message);
return true;
}
catch (Exception ex)
{
return false;
}
}
I see what you mean, the smtpapi-csharp project simply doesn't have that concept implemented.. but it's a trivial matter. (the value of this utility project is questionable to begin with).
Really the only piece of importance here is commented out.
//message.Headers.Add("X-SMTPAPI", xmstpapiJson);
Should be,
message.Headers.Add("X-SMTPAPI", #"{ ""asm_group_id"" : 777, ""asm_groups_to_display"" : [777] }");
Essentially, you're just assigning json to this header. The Documentation provides this sample
{
"asm_groups_to_display": [1, 2, 3]
}
[1, 2, 3] is an array of integers, which correlates to GroupIds.
Alternatively,
fork the git and add the following to Header.cs
/// <summary>
/// This sets which groups to display on the Manage Preferences page of an email. You can find further documentation about ASM here:
/// https://sendgrid.com/docs/API_Reference/SMTP_API/suppressions.html
/// </summary>
/// <param name="ids">ASM groups to display applied to the message</param>
public void SetAsmGroupsToDisplay(params int[] ids)
{
_settings.AddArray(new List<string> {"asm_groups_to_display"}, ids);
}
Build and update your csproj reference to use your forked project.
then, call SetAsmGroupsToDisplay like so,
private static string XsmtpapiHeaderAsJson()
{
var header = new Header();
header.SetAsmGroupId(777);
header.SetAsmGroupsToDisplay(777); // SetAsmGroupsToDisplay(new int[] {777}) works too
return header.JsonString();
}
and, of course, use the method:
message.Headers.Add("X-SMTPAPI", XsmtpapiHeaderAsJson());
... don't forgot to add a Pull Request when you get it working.

Send Notification Mail to Multiple users suing SMTP each having different Message

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.

Using .NET SmtpClient to Send mail alters the From name

I have written a method to send mail with attachments and authentication. Everything works perfectly except the From email address gets altered in the message received.
For example,
foo#example.com
Gets changed to,
-unknown-#example.com
The class I wrote is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Mail;
using System.IO;
class Email {
public MailAddress From { get; set; }
public string Host { get; set; }
public int Port { get; set; }
public Credentials SMTPAuth { get; set; }
public class Credentials {
public string Username { get; set; }
public string Password { get; set; }
}
public Email() {
SMTPAuth = new Credentials();
}
public List<Attachment> Attachments(params string[] file) {
List<Attachment> r = new List<Attachment>();
foreach ( string f in file ) {
if ( File.Exists( f ) ) {
r.Add(new Attachment(f));
}
}
return r;
}
public async Task<bool> SendMail( string Subject, string Message, MailAddressCollection To, MailPriority Priority, List<Attachment> Attachments ) {
bool result = false;
using ( SmtpClient s=new SmtpClient() ) {
NetworkCredential auth=new NetworkCredential( SMTPAuth.Username, SMTPAuth.Password );
s.Host=Host;
s.Port = Port;
s.UseDefaultCredentials = false;
s.Credentials=auth;
using ( MailMessage m=new MailMessage() ) {
m.From = From;
m.Subject = Subject;
m.IsBodyHtml = true;
m.Priority = Priority;
m.Body = Message;
foreach ( MailAddress t in To ) {
m.To.Add( t );
}
foreach(Attachment a in Attachments) {
m.Attachments.Add(a);
}
try {
await s.SendMailAsync(m);
result = true;
} catch ( SmtpFailedRecipientException ef ) {
} catch ( SmtpException es ) {
} catch ( Exception e ) {
}
}
return result;
}
}
}
And the way I am currently using it (testing), is as follows :
private async void button2_Click( object sender, EventArgs e ) {
Email m = new Email();
m.SMTPAuth.Username = "foo#example.com";
m.SMTPAuth.Password="mypassword";
m.Host = "mail.example.com";
m.Port = 366;
m.From = new System.Net.Mail.MailAddress("foo#example.com","Company Name - NoReply");
System.Net.Mail.MailAddressCollection c = new System.Net.Mail.MailAddressCollection();
c.Add("some.account#gmail.com");
List<Attachment> a = m.Attachments( #"D:\code.png" );
bool sent = await m.SendMail( "Testing", "<h1>Hello</h1>", c, System.Net.Mail.MailPriority.High, a );
this.Text = "Message Sent : " + sent.ToString();
}
Mail headers (from message received)
From: "Company Name - NoReply" <-unknown-#example.com>
To: example#gmail.com, support#example.com
Reply-To: "Company Name - NoReply" <noreply#example.com>
X-Priority: 1
Priority: urgent
Importance: high
Date: 1 May 2015 21:15:29 -0400
Subject: Testing
Content-Type: multipart/mixed;
boundary=--boundary_0_7310d152-dff2-4139-9db1-2558b3e70e73
X-ACL-Warn: {
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - mail.example.com
X-AntiAbuse: Original Domain - gmail.com
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - example.com
X-Get-Message-Sender-Via: mail.example.com: acl_c_relayhosts_text_entry: -unknown-#example.com|example.com
X-From-Rewrite: rewritten was: [noreply#example.com], actual sender does not match
How can I prevent it from changing the string preceding the # symbol in my from email address to -unknown- ? -- and why is it doing this ?
void Send(string email, string subject, string body)
{
SmtpClient client = new SmtpClient(_Host, _Port);
client.Timeout = _Timeout;
client.EnableSsl = _Ssl;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential(_Username, _Password);
MailMessage message = new MailMessage("No Reply <noreply#mysite.com>", email, subject, body);
message.BodyEncoding = UTF8Encoding.UTF8;
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
message.Sender = new MailAddress("noreply#mysite.com", "No Reply");
lock (this)
{
for (var count = 0; count < _MaxTryCount; ++count)
{
try
{
client.Send(message);
return;
}
catch (SmtpFailedRecipientsException)
{
return;
}
catch (SmtpException)
{
Thread.Sleep(_Timeout);
}
catch (Exception)
{
return;
}
}
}
}

Send Email by WebService

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.

Sending E-mail using C#

I need to send email via my C# app.
I come from a VB 6 background and had a lot of bad experiences with the MAPI control.
First of all, MAPI did not support HTML emails and second, all the emails were sent to my default mail outbox. So I still needed to click on send receive.
If I needed to send bulk html bodied emails (100 - 200), what would be the best way to do this in C#?
You could use the System.Net.Mail.MailMessage class of the .NET framework.
You can find the MSDN documentation here.
Here is a simple example (code snippet):
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
...
try
{
SmtpClient mySmtpClient = new SmtpClient("my.smtp.exampleserver.net");
// set smtp-client with basicAuthentication
mySmtpClient.UseDefaultCredentials = false;
System.Net.NetworkCredential basicAuthenticationInfo = new
System.Net.NetworkCredential("username", "password");
mySmtpClient.Credentials = basicAuthenticationInfo;
// add from,to mailaddresses
MailAddress from = new MailAddress("test#example.com", "TestFromName");
MailAddress to = new MailAddress("test2#example.com", "TestToName");
MailMessage myMail = new System.Net.Mail.MailMessage(from, to);
// add ReplyTo
MailAddress replyTo = new MailAddress("reply#example.com");
myMail.ReplyToList.Add(replyTo);
// set subject and encoding
myMail.Subject = "Test message";
myMail.SubjectEncoding = System.Text.Encoding.UTF8;
// set body-message and encoding
myMail.Body = "<b>Test Mail</b><br>using <b>HTML</b>.";
myMail.BodyEncoding = System.Text.Encoding.UTF8;
// text or html
myMail.IsBodyHtml = true;
mySmtpClient.Send(myMail);
}
catch (SmtpException ex)
{
throw new ApplicationException
("SmtpException has occured: " + ex.Message);
}
catch (Exception ex)
{
throw ex;
}
The best way to send bulk emails for more faster way is to use threads.I have written this console application for sending bulk emails.I have seperated the bulk email ID into two batches by creating two thread pools.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net.Mail;
namespace ConsoleApplication1
{
public class SendMail
{
string[] NameArray = new string[10] { "Recipient 1",
"Recipient 2",
"Recipient 3",
"Recipient 4",
"Recipient 5",
"Recipient 6",
"Recipient 7",
"Recipient 8",
"Recipient 9",
"Recipient 10"
};
public SendMail(int i, ManualResetEvent doneEvent)
{
Console.WriteLine("Started sending mail process for {0} - ", NameArray[i].ToString() + " at " + System.DateTime.Now.ToString());
Console.WriteLine("");
SmtpClient mailClient = new SmtpClient();
mailClient.Host = Your host name;
mailClient.UseDefaultCredentials = true;
mailClient.Port = Your mail server port number; // try with default port no.25
MailMessage mailMessage = new MailMessage(FromAddress,ToAddress);//replace the address value
mailMessage.Subject = "Testing Bulk mail application";
mailMessage.Body = NameArray[i].ToString();
mailMessage.IsBodyHtml = true;
mailClient.Send(mailMessage);
Console.WriteLine("Mail Sent succesfully for {0} - ",NameArray[i].ToString() + " at " + System.DateTime.Now.ToString());
Console.WriteLine("");
_doneEvent = doneEvent;
}
public void ThreadPoolCallback(Object threadContext)
{
int threadIndex = (int)threadContext;
Console.WriteLine("Thread process completed for {0} ...",threadIndex.ToString() + "at" + System.DateTime.Now.ToString());
_doneEvent.Set();
}
private ManualResetEvent _doneEvent;
}
public class Program
{
static int TotalMailCount, Mailcount, AddCount, Counter, i, AssignI;
static void Main(string[] args)
{
TotalMailCount = 10;
Mailcount = TotalMailCount / 2;
AddCount = Mailcount;
InitiateThreads();
Thread.Sleep(100000);
}
static void InitiateThreads()
{
//One event is used for sending mails for each person email id as batch
ManualResetEvent[] doneEvents = new ManualResetEvent[Mailcount];
// Configure and launch threads using ThreadPool:
Console.WriteLine("Launching thread Pool tasks...");
for (i = AssignI; i < Mailcount; i++)
{
doneEvents[i] = new ManualResetEvent(false);
SendMail SRM_mail = new SendMail(i, doneEvents[i]);
ThreadPool.QueueUserWorkItem(SRM_mail.ThreadPoolCallback, i);
}
Thread.Sleep(10000);
// Wait for all threads in pool to calculation...
//try
//{
// // WaitHandle.WaitAll(doneEvents);
//}
//catch(Exception e)
//{
// Console.WriteLine(e.ToString());
//}
Console.WriteLine("All mails are sent in this thread pool.");
Counter = Counter+1;
Console.WriteLine("Please wait while we check for the next thread pool queue");
Thread.Sleep(5000);
CheckBatchMailProcess();
}
static void CheckBatchMailProcess()
{
if (Counter < 2)
{
Mailcount = Mailcount + AddCount;
AssignI = Mailcount - AddCount;
Console.WriteLine("Starting the Next thread Pool");
Thread.Sleep(5000);
InitiateThreads();
}
else
{
Console.WriteLine("No thread pools to start - exiting the batch mail application");
Thread.Sleep(1000);
Environment.Exit(0);
}
}
}
}
I have defined 10 recepients in the array list for a sample.It will create two batches of emails to create two thread pools to send mails.You can pick the details from your database also.
You can use this code by copying and pasting it in a console application.(Replacing the program.cs file).Then the application is ready to use.
I hope this helps you :).
Code:
using System.Net.Mail
new SmtpClient("smtp.server.com", 25).send("from#email.com",
"to#email.com",
"subject",
"body");
Mass Emails:
SMTP servers usually have a limit on the number of connection hat can handle at once, if you try to send hundreds of emails you application may appear unresponsive.
Solutions:
If you are building a WinForm then use a BackgroundWorker to process the queue.
If you are using IIS SMTP server or a SMTP server that has an outbox folder then you can use SmtpClient().PickupDirectoryLocation = "c:/smtp/outboxFolder"; This will keep your system responsive.
If you are not using a local SMTP server than you could build a system service to use Filewatcher to monitor a forlder than will then process any emails you drop in there.
The .NET framework has some built-in classes which allows you to send e-mail via your app.
You should take a look in the System.Net.Mail namespace, where you'll find the MailMessage and SmtpClient classes.
You can set the BodyFormat of the MailMessage class to MailFormat.Html.
It could also be helpfull if you make use of the AlternateViews property of the MailMessage class, so that you can provide a plain-text version of your mail, so that it can be read by clients that do not support HTML.
http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.alternateviews.aspx
You can send email using SMTP or CDO
using SMTP:
mail.From = new MailAddress("your_email_address#gmail.com");
mail.To.Add("to_address");
mail.Subject = "Test Mail";
mail.Body = "This is for testing SMTP mail from GMAIL";
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("username", "password");
SmtpServer.EnableSsl = true;
using CDO
CDO.Message oMsg = new CDO.Message();
CDO.IConfiguration iConfg;
iConfg = oMsg.Configuration;
ADODB.Fields oFields;
oFields = iConfg.Fields;
ADODB.Field oField = oFields["http://schemas.microsoft.com/cdo/configuration/sendusing"];
oFields.Update();
oMsg.Subject = "Test CDO";
oMsg.From = "from_address";
oMsg.To = "to_address";
oMsg.TextBody = "CDO Mail test";
oMsg.Send();
Source : C# SMTP Email
Source: C# CDO Email
I can strongly recommend the aspNetEmail library: http://www.aspnetemail.com/
The System.Net.Mail will get you somewhere if your needs are only basic, but if you run into trouble, please check out aspNetEmail. It has saved me a bunch of time, and I know of other develoeprs who also swear by it!
Use the namespace System.Net.Mail. Here is a link to the MSDN page
You can send emails using SmtpClient class.
I paraphrased the code sample, so checkout MSDNfor details.
MailMessage message = new MailMessage(
"fromemail#contoso.com",
"toemail#contoso.com",
"Subject goes here",
"Body goes here");
SmtpClient client = new SmtpClient(server);
client.Send(message);
The best way to send many emails would be to put something like this in forloop and send away!
Take a look at the FluentEmail library.
I've blogged about it here
You have a nice and fluent api for your needs:
Email.FromDefault()
.To("you#domain.com")
.Subject("New order has arrived!")
.Body("The order details are…")
.Send();
Let's make something as a full solution :). Maybe it can help as well.
It is a solution for sending one email content and one attach file (or without attach) to many Email addresses. Of course sending just one email is possibility as well. Result is List object with data what is OK and what is not.
namespace SmtpSendingEmialMessage
{
public class EmailSetupData
{
public string EmailFrom { get; set; }
public string EmailUserName { get; set; }
public string EmailPassword { get; set; }
public string EmailSmtpServerName { get; set; }
public int EmailSmtpPortNumber { get; set; }
public Boolean SSLActive { get; set; } = false;
}
public class SendingResultData
{
public string SendingEmailAddress { get; set; }
public string SendingEmailSubject { get; set; }
public DateTime SendingDateTime { get; set; }
public Boolean SendingEmailSuccess { get; set; }
public string SendingEmailMessage { get; set; }
}
public class OneRecData
{
public string RecEmailAddress { get; set; } = "";
public string RecEmailSubject { get; set; } = "";
}
public class SendingProcess
{
public string EmailCommonSubjectOptional { get; set; } = "";
private EmailSetupData EmailSetupParam { get; set; }
private List<OneRecData> RecDataList { get; set; }
private string EmailBodyContent { get; set; }
private Boolean IsEmailBodyHtml { get; set; }
private string EmailAttachFilePath { get; set; }
public SendingProcess(List<OneRecData> MyRecDataList, String MyEmailTextContent, String MyEmailAttachFilePath, EmailSetupData MyEmailSetupParam, Boolean EmailBodyHtml)
{
RecDataList = MyRecDataList;
EmailBodyContent = MyEmailTextContent;
EmailAttachFilePath = MyEmailAttachFilePath;
EmailSetupParam = MyEmailSetupParam;
IsEmailBodyHtml = EmailBodyHtml;
}
public List<SendingResultData> SendAll()
{
List<SendingResultData> MyResList = new List<SendingResultData>();
foreach (var js in RecDataList)
{
using (System.Net.Mail.MailMessage MyMes = new System.Net.Mail.MailMessage())
{
DateTime SadaJe = DateTime.Now;
Boolean IsOK = true;
String MySendingResultMessage = "Sending OK";
String MessageSubject = EmailCommonSubjectOptional;
if (MessageSubject == "")
{
MessageSubject = js.RecEmailSubject;
}
try
{
System.Net.Mail.MailAddress MySenderAdd = new System.Net.Mail.MailAddress(js.RecEmailAddress);
MyMes.To.Add(MySenderAdd);
MyMes.Subject = MessageSubject;
MyMes.Body = EmailBodyContent;
MyMes.Sender = new System.Net.Mail.MailAddress(EmailSetupParam.EmailFrom);
MyMes.ReplyToList.Add(MySenderAdd);
MyMes.IsBodyHtml = IsEmailBodyHtml;
}
catch(Exception ex)
{
IsOK = false;
MySendingResultMessage ="Sender or receiver Email address error." + ex.Message;
}
if (IsOK == true)
{
try
{
if (EmailAttachFilePath != null)
{
if (EmailAttachFilePath.Length > 5)
{
MyMes.Attachments.Add(new System.Net.Mail.Attachment(EmailAttachFilePath));
}
}
}
catch (Exception ex)
{
IsOK = false;
MySendingResultMessage ="Emial attach error. " + ex.Message;
}
if (IsOK == true)
{
using (System.Net.Mail.SmtpClient MyCl = new System.Net.Mail.SmtpClient())
{
MyCl.EnableSsl = EmailSetupParam.SSLActive;
MyCl.Host = EmailSetupParam.EmailSmtpServerName;
MyCl.Port = EmailSetupParam.EmailSmtpPortNumber;
try
{
MyCl.Credentials = new System.Net.NetworkCredential(EmailSetupParam.EmailUserName, EmailSetupParam.EmailPassword);
}
catch (Exception ex)
{
IsOK = false;
MySendingResultMessage = "Emial credential error. " + ex.Message;
}
if (IsOK == true)
{
try
{
MyCl.Send(MyMes);
}
catch (Exception ex)
{
IsOK = false;
MySendingResultMessage = "Emial sending error. " + ex.Message;
}
}
}
}
}
MyResList.Add(new SendingResultData
{
SendingDateTime = SadaJe,
SendingEmailAddress = js.RecEmailAddress,
SendingEmailMessage = MySendingResultMessage,
SendingEmailSubject = js.RecEmailSubject,
SendingEmailSuccess = IsOK
});
}
}
return MyResList;
}
}
}
public string sendEmail(string mail,string subject, string body)
{
try
{
MailMessage message = new MailMessage();
SmtpClient smtp = new SmtpClient();
message.From = new MailAddress("example#gmail.com");
message.To.Add(new MailAddress(mail));
message.Subject = subject;
message.IsBodyHtml = true; //to make message body as html
message.Body = body;
smtp.Port = 587;
smtp.Host = "smtp.gmail.com"; //for gmail host
smtp.EnableSsl = true;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential("example#gmail.com", "password");
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Send(message);
return "success";
}
catch (Exception e) {
return e.Message;
}
}‏
You can use Mailkit. MailKit is an Open Source cross-platform .NET mail-client library that is based on MimeKit and optimized for mobile devices.
It has more and advance features better than System.Net.Mail
A fully-cancellable Pop3Client with support for STLS, UIDL, APOP, PIPELINING, UTF8, and LANG. Client-side sorting and threading of
messages (the Ordinal Subject and the Jamie Zawinski threading
algorithms are supported).
Asynchronous versions of all methods that hit the network.
S/MIME, OpenPGP and DKIM signature support via MimeKit.
Microsoft TNEF support via MimeKit.
See this example you can send mail
MimeMessage mailMessage = new MimeMessage();
mailMessage.From.Add(new MailboxAddress(senderName, sender#address.com));
mailMessage.Sender = new MailboxAddress(senderName, sender#address.com);
mailMessage.To.Add(new MailboxAddress(emailid, emailid));
mailMessage.Subject = subject;
mailMessage.ReplyTo.Add(new MailboxAddress(replyToAddress));
mailMessage.Subject = subject;
var builder = new BodyBuilder();
builder.TextBody = "Hello There";
try
{
using (var smtpClient = new SmtpClient())
{
smtpClient.Connect("HostName", "Port", MailKit.Security.SecureSocketOptions.None);
smtpClient.Authenticate("user#name.com", "password");
smtpClient.Send(mailMessage);
Console.WriteLine("Success");
}
}
catch (SmtpCommandException ex)
{
Console.WriteLine(ex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
You can download from here.
Below the attached solution work over local machine and server.
public static string SendMail(string bodyContent)
{
string sendMail = "";
try
{
string fromEmail = "from#gmail.com";
MailMessage mailMessage = new MailMessage(fromEmail, "to#gmail.com", "Subject", body);
mailMessage.IsBodyHtml = true;
SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", 587);
smtpClient.EnableSsl = true;
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential(fromEmail, frompassword);
smtpClient.Send(mailMessage);
}
catch (Exception ex)
{
sendMail = ex.Message.ToString();
Console.WriteLine(ex.ToString());
}
return sendMail;
}
To not make your data exposed and right procedure set them in the appsetting
using MailKit.Net.Smtp;
using Microsoft.EntityFrameworkCore;
using MimeKit;
namespace Admin.Services
{
public class EmailService
{
private readonly string _from;
private readonly string _host;
private readonly int _port;
private readonly string _smtpUser;
private readonly string _smtpPassword;
private readonly IHttpContextAccessor _contextAccessor;
private readonly Context _Context;
private readonly PassResetByEmailService _passResetByEmailService;
public EmailService(
Context Context,
IConfiguration configuration,
IHttpContextAccessor contextAccessor,
PassResetByEmailService passResetByEmailService
)
{
_from = configuration["EmailConfig:From"];
_host = configuration["EmailConfig:Host"];
_port = int.Parse(configuration["EmailConfig:Port"]);
_smtpUser = configuration["EmailConfig:UserName"];
_smtpPassword = configuration["EmailConfig:Password"];
_passResetByEmailService = passResetByEmailService;
_Context = Context;
_contextAccessor = contextAccessor;
}
public async Task<string?> SendPassEmail(string email)
{
//Check email nel DB
var remail = await _grabcadContext.UTENTE.FirstOrDefaultAsync(c => c.EMAIL == email && !c.FLG_DISABILITATO && !c.FLG_ELIMINATO);
if (remail == null)
return "Email non trovata";
var request = _contextAccessor.HttpContext.Request;
var requestUrl = $"{request.Scheme}://{request.Host}{request.PathBase}";
var resetPasswordUrl = $"{requestUrl}/Account/ResetPasswordToken";
var token = await _passResetByEmailService.AddPassResetByEmailService(email);
var subject = "Reset password";
var content = $"link: {resetPasswordUrl}?email={email}&token={token}";
using (var client = new SmtpClient())
{
try
{
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress(_from, _from));
emailMessage.To.Add(new MailboxAddress(email, email));
emailMessage.Subject = subject;
emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Text) { Text = content };
await client.ConnectAsync(_host, _port, true);
client.AuthenticationMechanisms.Remove("XOAUTH2");
await client.AuthenticateAsync(_smtpUser, _smtpPassword);
await client.SendAsync(emailMessage);
}
catch (Exception ex)
{
throw;
}
finally
{
await client.DisconnectAsync(true);
client.Dispose();
}
}
return null;
}
}
}
appsettings.json
"SysAdminEmail": "name#smt.com ",
"HostPort": {
"Port": 587,
"Host": "smtp.com"
}
}

Categories

Resources