Is there any way I can track (through the code) the bounced emails.
Consider the email id like 'skdfisdcnsodioifs#gmail.com'. This is valid email id but does not exists so certainly it will be bounced backed.
I am using ASP.Net's SmtpClient with "message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure". However it still shows the message sent successfully and after ~20-25 minutes I get the fail delivery notification email.
Below is my code
class Program
{
static void Main(string[] args)
{
SmtpClient client = new SmtpClient("xxxx.xxxxxx.xxx", 25);
client.Credentials = new NetworkCredential("xxxxxx#xxxxxx.com", "xxxxxx");
MailAddress to = new MailAddress("abcdsfasdfasdfasdfasdf2342342defgh#gmail12333.com");
MailAddress from = new MailAddress("xxxxxx#xxxxxx.com");
MailMessage message = new MailMessage(from, to);
message.Headers.Add("Return-Path", "xxxxxx#gmail.com");
message.ReplyToList.Add(new MailAddress("xxxxxx#gmail.com"));
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure | DeliveryNotificationOptions.OnSuccess;
message.Subject = "Test POC";
message.Body = "This is a test e-mail message sent by an application. ";
client.SendCompleted += client_SendCompleted;
string UserState = "test";
client.Timeout = 3;
try
{
Console.WriteLine("start to send email ...");
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.SendAsync(message,UserState);
Console.WriteLine("email was sent successfully!");
}
catch (SmtpFailedRecipientsException ep)
{
Console.WriteLine("failed to send email with the following error:");
Console.WriteLine(ep.Message);
}
catch (Exception ep)
{
Console.WriteLine("failed to send email with the following error:");
Console.WriteLine(ep.Message);
}
Console.WriteLine("test.");
Console.ReadKey();
}
static void client_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
//String token = (string)e.UserState;
if (e.Cancelled)
{
Console.WriteLine("Send canceled.");
}
if (e.Error != null)
{
Console.WriteLine("[{0}] ", e.Error.ToString());
}
else
{
Console.WriteLine("Message sent.");
}
}
}
Thanks in advance.
Abhishek
Related
I am trying to send mail using GoDaddy mail server with SMTPClient in ASP.NET and my code is below , I have tried all the ports in GoDaddy but i couldn't send a mail
My code:
try
{
//Mail Message
MailMessage mM = new MailMessage();
//Mail Address
mM.From = new MailAddress("xxx#sender.com");
//receiver email id
mM.To.Add("xxx#receiver.com");
//subject of the email
mM.Subject = "your subject line will go here";
mM.Body = "Body of the email";
mM.IsBodyHtml = true;
//SMTP client
SmtpClient sC = new SmtpClient();
//credentials to login in to hotmail account
sC.Credentials = new NetworkCredential(username, password);
//port number for Hot mail
sC.Port = 25;
sC.Host = "smtpout.asia.secureserver.net";
sC.UseDefaultCredentials = false;
//enabled SSL
sC.EnableSsl = false;
sC.DeliveryMethod = SmtpDeliveryMethod.Network;
sC.Timeout = 40000;
//Send an email
sC.Send(mM);
}
catch (Exception ex)
{
var temp = ex.Message;
}
I have also used port no 465 with enablessl = true but no success
I was struggling with this too and found a solution.
The problem is that GoDaddy uses Implicit SSL (SMTPS) and this is NOT supported with System.Net.Mail.
It should be possible to use a GoDady Relay account, but then you can only send 250 emails per day AND the email sent will be SPAM unvisible at receiver side!
Then I found an open source library: http://sourceforge.net/projects/netimplicitssl/
You can get this package via NuGet in Visual Studio.
Search for: Aegis Implicit Mail.
I can tell you that this works perfectly !
private void _SendEmail()
{
try
{
var mail = "YourEmail#YourGoDaddyWebsite.com";
var host = "smtpout.europe.secureserver.net";
var user = "YourEmail#YourGoDaddyWebsite.com";
var pass = "YourGoDaddyPassword!";
//Generate Message
var message = new MimeMailMessage();
message.From = new MimeMailAddress(mail);
message.To.Add("receiver#website.com");
message.Subject = "Subject Text...";
message.Body = "Body Text...";
//Create Smtp Client
var mailer = new MimeMailer(host, 465);
mailer.User = user;
mailer.Password = pass;
mailer.SslType = SslMode.Ssl;
mailer.AuthenticationMode = AuthenticationType.Base64;
//Set a delegate function for call back
mailer.SendCompleted += compEvent;
mailer.SendMailAsync(message);
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
private void compEvent(object sender, AsyncCompletedEventArgs e)
{
if (e.UserState != null)
Console.Out.WriteLine(e.UserState.ToString());
Console.Out.WriteLine("is it canceled? " + e.Cancelled);
if (e.Error != null)
Console.Out.WriteLine("Error : " + e.Error.Message);
}
you should note you cannot sent non-html, or plain text emails. The message.IsBodyHtml member does not seem to work currently.
I have this code
protected void ASPxButton1_Click(object sender, EventArgs e)
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress("paragonadmin#qss.co.za", "Paragon Admin");
mail.To.Add(new MailAddress("dewald#qss.co.za", "Appointment Scheduled"));
mail.Subject = "Enter mail subject";
mail.Body = "Enter mail body";
SmtpClient smtpClient = new SmtpClient("smtp.qss.co.za");
smtpClient.Credentials = new System.Net.NetworkCredential("paragonadmin#qss.co.za", "123456");
Object state = mail;
//event handler for asynchronous call
smtpClient.SendCompleted += new SendCompletedEventHandler(smtpClient_SendCompleted);
try
{
//smtpClient.Send(mail);
smtpClient.SendAsync(mail, state);
}
catch (Exception ex) { /* exception handling code here */ }
}
void smtpClient_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
MailMessage mail = e.UserState as MailMessage;
if (!e.Cancelled && e.Error != null)
{
ASPxLabel1.Text = "Mail sent successfully";
}
}
It is supposed to send a mail asynchronous in my application, but for some reason I get a "Failure sending mail" error message.
Any advice
I have to send mail to multiple recipient eg. to all the employee of an organization. For this I go through the resources via search engine and decided to make multiple instant of SmtpClient and send mail using async. So for test I write following code having gmail test server.
public void SendMail()
{
try
{
string strEmail = string.Empty;
// for collecting multiple recepient
//foreach (GridViewRow grd in gdv_txtMailTo.Rows)
//{
// CheckBox chkBx = (CheckBox)grd.FindControl("chkBxSelect");
// if (chkBx != null && chkBx.Checked)
// {
// strEmail += ((Label)grd.FindControl("Label1")).Text + ',';
// }
//}
strEmail = "yogendra.paudyal44#gmail.com";
string emails = strEmail;
string output = DBNull.Value.ToString();
//if (emails != "")
//{
// output = emails.Remove(emails.Length - 1, 1);
//}
MassMail_Controller.SaveSelectedEmails(output, PortalID);
MassMail_Info info = new MassMail_Info();
info.SendFrom = txtMailFrom.Text;
info.Subject = txtSubject.Text;
info.CC = txtCC.Text;
info.BCC = txtBCC.Text;
info.FileName = "";
info.SendTo = strEmail;
string messageTemplate = txtBody.Text;
info.Body = messageTemplate;
info.UserModuleId = UserModuleID;
info.PortalId = PortalID;
for (int i = 0; i < 50; i++) {
MailHelper.SendMailOneAttachment(info.SendFrom, info.SendTo, info.Subject, info.Body, info.FileName, info.CC, info.BCC);
}
//Thread thread = new Thread(new ParameterizedThreadStart(GetAllEmail));
//thread.IsBackground = true;
//thread.Start(bit);
//while (thread.IsAlive)
//{
// ShowMessage(SageMessageTitle.Exception.ToString(), "Mail Sent", "", SageMessageType.Success);
//}
}
catch (Exception ex)
{
ProcessException(ex);
}
}
And mailHelper would be:
public static void SendEMail(string From, string sendTo, string Subject, string Body, ArrayList AttachmentFiles, string CC, string BCC, bool IsHtmlFormat)
{
SageFrameConfig sfConfig = new SageFrameConfig();
//string ServerPort = sfConfig.GetSettingValueByIndividualKey(SageFrameSettingKeys.SMTPServer);
//string SMTPAuthentication = sfConfig.GetSettingValueByIndividualKey(SageFrameSettingKeys.SMTPAuthentication);
//string SMTPEnableSSL = sfConfig.GetSettingValueByIndividualKey(SageFrameSettingKeys.SMTPEnableSSL);
//string SMTPPassword = sfConfig.GetSettingValueByIndividualKey(SageFrameSettingKeys.SMTPPassword);
//string SMTPUsername = sfConfig.GetSettingValueByIndividualKey(SageFrameSettingKeys.SMTPUsername);
string ServerPort = (SageFrameSettingKeys.SMTPServer);
string SMTPAuthentication =(SageFrameSettingKeys.SMTPAuthentication);
string SMTPEnableSSL = (SageFrameSettingKeys.SMTPEnableSSL);
string SMTPPassword = (SageFrameSettingKeys.SMTPPassword);
string SMTPUsername = (SageFrameSettingKeys.SMTPUsername);
string[] SMTPServer = ServerPort.Split(':');
try
{
MailMessage myMessage = new MailMessage();
myMessage.To.Add(sendTo);
myMessage.From = new MailAddress(From);
myMessage.Subject = Subject;
myMessage.Body = Body;
myMessage.IsBodyHtml = true;
if (CC.Length != 0)
myMessage.CC.Add(CC);
if (BCC.Length != 0)
myMessage.Bcc.Add(BCC);
if (AttachmentFiles != null)
{
foreach (string x in AttachmentFiles)
{
if (File.Exists(x)) myMessage.Attachments.Add(new Attachment(x));
}
}
SmtpClient smtp = new SmtpClient();
if (SMTPAuthentication == "1")
{
if (SMTPUsername.Length > 0 && SMTPPassword.Length > 0)
{
smtp.Credentials = new System.Net.NetworkCredential(SMTPUsername, SMTPPassword);
}
}
smtp.EnableSsl = bool.Parse(SMTPEnableSSL.ToString());
if (SMTPServer.Length > 0)
{
if (SMTPServer[0].Length != 0)
{
smtp.Host = SMTPServer[0];
if (SMTPServer.Length == 2)
{
smtp.Port = int.Parse(SMTPServer[1]);
}
else
{
smtp.Port = 25;
}
object userState = myMessage;
//wire up the event for when the Async send is completed
smtp.SendCompleted += new
SendCompletedEventHandler(SendCompletedCallback);
smtp.SendAsync(myMessage,userState);
Console.WriteLine("Sending message... press c to cancel mail. Press any other key to exit.");
//string answer = Console.ReadLine();
// If the user canceled the send, and mail hasn't been sent yet,
// then cancel the pending operation.
//if (answer.StartsWith("c"))
//{
// smtp.SendAsyncCancel();
//}
//// Clean up.
//myMessage.Dispose();
Console.WriteLine("Goodbye.");
}
else
{
throw new Exception("SMTP Host must be provided");
}
}
}
catch (Exception ex)
{
throw ex;
}
}
This code snippet works fine but I couldnot send specified number of mail. The number of email sent is differnt each time I execute this code ie. it may be 35, 40, 42 etc. It seems some instances of SmtpClient got failed, but I didnot get any exception. Am I doing something wrong. Do We have better option to send multiple mail at one time?
I want to share my experience with sending emails.I also used to send B-Day emails but in my case there were usually 100-150 people and all mails delivered successfully. I had made a web service for this whose only task was to send emails. But before emails started to deliver successfully we tested on local machine which worked fine but when we tested it on server i face the same issue and cause of this failure was that we deployed our web service in .Net framework 2.0 than we changed it to 4.0 and tested it again with 10000,5000,1000 emails and it worked fine not all emails but most of them reached destination.Also one more thing to mention is that the address from which we were sending email was restricted by network department in email server to send only 100 emails.Also try to avoid sending too many emails from one sender and from one email server because you can get black listed.
Summary
First of all check that are you using .Net framework 2.0 if yes
switch to 4.0.
Make sure that there are no restrictions by network department at
email server and also to address which you use as sender.
Place all your code in using statement to make sure objects get
disposed.
Send your emails in chunks(About 100 at a time).
using()
{
//Place you email sending code here.
}
I've written code for sending a newsletter, all is working fine, but there is a problem if one of the email addresses in the list, doesn't exit or the domain does not exist.
In this case the script stops immediately and the sending of the mail list is not finished.
Here is the part of the code I want to modify.
public static void SendMessage(String sender, String recipient, String message, String object)
{
try
{
MailMessage mail = new MailMessage(sender, recipient);
mail.Subject = object;
mail.IsBodyHtml = true;
mail.Body = message;
SmtpClient smtp = new SmtpClient();
smtp.Host = "my.smtp.com";
smtp.Send(mail);
}
catch (Exception e)
{ throw new Exception("AdminEmail - SendMessage >> recipient: " + recipient + " - generic error: " + e.Message); }
}
Hope somone can help me, thank you very much!
Welcome to SO.
From what I can infer from your description your are not handling the exception that is thrown by SendMessage.
Handle the exception in the caller method. Or do a dirty fix as shown below...
This is not a real fix. But will help you understand the issue...You have to determine in your calling method what to do if SendMessage throws an exception.
public static void SendMessage(String sender, String recipient, String message, String object)
{
try
{
MailMessage mail = new MailMessage(sender, recipient);
mail.Subject = object;
mail.IsBodyHtml = true;
mail.Body = message;
SmtpClient smtp = new SmtpClient();
smtp.Host = "my.smtp.com";
smtp.Send(mail);
}
catch (Exception e)
{
//Just log error and continue to process
}
}
I am using SendAsync to send an email. The reason I'm using async is simply to free up the UI rather than send multiple emails.
I have created the following callback event:
static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
var client = sender as SmtpClient;
var message = e.UserState as MailMessage;
if (e.Error.IsNotNull())
{
if (e.Error is SmtpFailedRecipientException)
{
var status = ((SmtpFailedRecipientException)(e.Error)).StatusCode;
if (status == SmtpStatusCode.MailboxBusy ||
status == SmtpStatusCode.MailboxUnavailable ||
status == SmtpStatusCode.TransactionFailed)
{
// a new message!
}
else
{
// TODO: Log other uncaught recipient failures
}
}
else
{
// TODO: Log all other failure reasons
}
}
client.Dispose();
message.Dispose();
}
As you can see I'm attempting to catch some recipients failures. If I find such an exception I want to try and resend the email.
I'm trying to work out how to resend the email safely. I'm thinking to create a new SmtpClient rather than reuse the existing one, but to be honest, I'm fairly new to .net and I'm not so sure of the implications.
Any advice would be appreciated.
Sending email asynchronously without delaying response back to the client(UI) requires a Backgroundworker in .Net. I implemented this on my site and will share the class source code with you.
using System;
using System.Collections.Generic;
using System.Web;
using System.ComponentModel; //Background worker namespace
using System.Net.Mail;
/// <summary>
/// Summary description for ClassName
/// </summary>
///
public class postmail
{
BackgroundWorker bw = new BackgroundWorker();
string email1, subject1, message1, failedemails;
public postmail(string email, string subject, string message)
{
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
email1 = email;
subject1 = subject;
message1 = message;
}
public postmail()
{
// TODO: Complete member initialization
}
public void startsending() {
bw.RunWorkerAsync();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Flush(); // send all buffered output to client
HttpContext.Current.Response.End();
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
var finalemail = email1.Split(new[] { ',' }, StringSplitOptions.None);
//loop through the email addresses and send individually
for (int c = 0; c < finalemail.Length; c++) {
try
{
MailMessage mailMessage = new MailMessage();
// Sender Address
mailMessage.From = new MailAddress("emailaddress");
// Recepient Address
mailMessage.To.Add(finalemail[c].ToString());
// Subject
mailMessage.Subject = subject1.ToString();
// Body
mailMessage.Body = message1.ToString();
// format of mail message
mailMessage.IsBodyHtml = true;
// new instance of Smtpclient
SmtpClient mailSmtpClient = new SmtpClient("mail server");
//mailSmtpClient.EnableSsl = true;
mailSmtpClient.Credentials = new System.Net.NetworkCredential("emailaddress", "password");
// mail sent
Object userState = mailMessage;
mailSmtpClient.SendAsync(mailMessage, userState);
}
catch (Exception exc)
{
//fix for you
var ext = exc.ToString(); //catch exception for failed message
failedemails = failedemails + finalemail[c] + ","; //create a string of failed emails
}
}
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//called when the background process is done working
if(failedemails != null){
postmail(failedemails, subject1, message1); //resend the failed email
startsending();
}
}
}
Your concept might not be exact like mine but the key methods are:
Create an event handlers for the BackgroundWorker.
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
try
{
//Send your mail
}
catch (Exception exc)
{
//Catch exception here and call the resend method
}
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//do something after completion
}
The fix i made for you was to build a string of all failed addresses, then resend them after the backgroundworker is done working. cheers!!