Read multiple posts about .net mail delivery notifications and tested multiple things:
Trying to send mail via SMTP. No mails arrives and no exception error
https://msdn.microsoft.com/en-us/library/system.net.mail.smtpfailedrecipientsexception.aspx
How to check MailMessage was delivered in .NET?
https://www.emailarchitect.net/easendmail/sdk/html/o_deliverynotificationoptions.htm
http://forums.asp.net/p/1189023/2038523.aspx
Though I'm still stuck. What I want to accomplish is the following: I only want to know if the email-address which the mail is send to is valid, and not valid as in a valid format but valid as in: does the email address exist.
Sometimes a user will send an email to an address but by accident types 1 letter wrong, the mail is valid since it contains a domain and # but the mail address doesn't exist. The sender will think it has been send correctly since they didn't receive any notification.
I want to make sure the sender gets the undelivered notification.
When using code to send mails through Outlook for example you automatically get a undelivered message if the mail address doesn't exists, however with SMTP (I am) not so lucky. I tried it with this bit of code:
using (var msg = new MailMessage())
using (var client = new SmtpClient("spamfilter.mySpamFilter.com", 587))
{
msg.IsBodyHtml = true;
msg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
msg.From = new MailAddress(FromAddress);
msg.To.Add(TO);
msg.Body = Body;
msg.Subject = Subject;
//Send mail
try
{
client.Send(msg);
}
catch (SmtpFailedRecipientsException ex)
{
throw ex;
}
}
For the To address I created an address that is 100% invalid. Though, the exception is never reached.
Can the spamfilter be the problem? For example, when I check the spamfilter I can see the messages have the refused send status for the invalid email addresses but the action status is allowed (so no spam). So it looks like the spamfilter never returns the exception back to the code.
Or is it just not possible what I want to achieve?
Spamfilter:
I dont think that you will get an error here because the To Method takes either an string or an MailAdress which will also takes an string as input.
So every Adress will be accepted here.
Have you tried to place some not allowd characters like ' " % or something like this?
I guess you will get an exception here.
Everything else will be forwared to the smtp and the he will take care of the delivery and not your C# Code.
Regards
Andre
Related
Getting the exception:
Failure sending mail.
While using System.Net.Mail.Smtp
in C#.NET on the line smtp.Send(message);
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
message.To.Add(sendto);
message.Subject = "CP1 Lab Password";
message.From = new System.Net.Mail.MailAddress("abc#gmail.com");
message.Body = mail_message;
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("yoursmtphost");
smtp.Host = "smtp.gmail.com";
smtp.Port = 465; //(465 for SSL)587
smtp.EnableSsl = true;
smtp.Credentials = new System.Net.NetworkCredential("abc#gmail.com", "mypassword");
smtp.Send(message);
Edit 1:
Here is the detail of the error:
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 ...
The same error when using port 25.
Few months before this code used to work but today it is not working
As from your exception message (incomplete) and the code, it is very hard to say what went wrong in your case. Failure sending mail is thrown when the server is not found, port cannot be connected. It means that connection was not established, until now.
The exception message that gets raised if the connection was established but authentication was not performed correctly is, "The SMTP server requires an authenticated connection...". I would suggest that you check the PORT, SMTP server host (do not add http://) and then re-try. An SMTP connection (in most general cases) requires
SMTP Server host: smtp.gmail.com is enough!
PORT to connect at: I have always used default TCP port for SMTP, 25. It works.
EnableSsl: most require it. I suggest you always use it. client.EnableSsl = true;
Credentials are required by all: No server would allow bots sending emails. In this concern, if you create a new account. You may face trouble sending emails programmatically, I faced the problem with a new account not sending the emails whereas an old account (default account of mine) was sending the email without any trouble.
The following code template (if filled with accurate parameters) will definitely send the email, because I have tested and verified it bazillion times. :)
// You should use a using statement
using (SmtpClient client = new SmtpClient("<smtp-server-address>", 25))
{
// Configure the client
client.EnableSsl = true;
client.Credentials = new NetworkCredential("<username>", "<password>");
// client.UseDefaultCredentials = true;
// A client has been created, now you need to create a MailMessage object
MailMessage message = new MailMessage(
"from#example.com", // From field
"to#example.com", // Recipient field
"Hello", // Subject of the email message
"World!" // Email message body
);
// Send the message
client.Send(message);
/*
* Since I was using Console app, that is why I am able to use the Console
* object, your framework would have different ones.
* There is actually no need for these following lines, you can ignore them
* if you want to. SMTP protocol would still send the email of yours. */
// Print a notification message
Console.WriteLine("Email has been sent.");
// Just for the sake of pausing the application
Console.Read();
}
Sending an email may be a headache sometimes, because it requires some basic understanding of networking also. I have written an article that covers sending emails in .NET framework and a few problems that beginners usually stumble upon such as this one. You may be interested in reading that article also.
http://www.codeproject.com/Articles/873250/Sending-emails-over-NET-framework-and-general-prob
The code below can fail due to a lot of causes, e.g., invalid recipients list or nonexistent recipients.
For these problems the sender of the mail will get non-delivered report to his inbox.
What I want to achieve is, if the sent email fails because of improper recipient id, then I should intercept the Exception at Catch branch.
try
{
Outlook.MailItem mail = OutLookInstance.CreateItem(Outlook.OlItemType.olMailItem);
mail.Subject = "Send to TAM";
mail.Recipients.Add("v-sanshr#microsoft.com");
mail.Body = "Business Alert mail";
mail.Display(false);
mail.OriginatorDeliveryReportRequested = true;
mail.Send();
}
catch(Exception ex)
{
}
The above code is supposed to do that, but it does not throw any exception if the delivery fails.
How to achieve this using Outlook, please let me know?
You need to use the Resolve or ResolveAll methods of the Recipient or Recipients class to resolve a Recipient object against the Address Book.
You can find a sample code in C# and VB.NET in the How To: Create and send an Outlook message programmatically article.
I have a very simple email form that sends out the email using department email account to given recipients. However, the company makes the password expire every 90 days, and there's a web form that I created where the authorized user can go and change the password/email address for the form.
Here's the code:
SmtpClient smtp = new SmtpClient();
smtp.Host = host;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new System.Net.NetworkCredential(username, password);
try
{
smtp.Send(iEditMail);
}
catch(SmtpException exception)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, exception.Message + " Make sure the username and password is correct.");
}
Since user is responsible for entering the password, they may accidentally enter the wrong password for the email account or the password may expire. I need to be able to catch this so it can be notified to users who are trying to send email. (Btw, this is only for departmental use). How can I make sure if the credentials are correct before sending the email. Right now it doesn't throw any error to tell the email wasn't sent - we just don't receive it.
First:
If you can, it is better to create a service account and use those credentials. That way there is no need to change the credentials periodically. (#mason's suggestion)
However, if that is not possible:
According to MSDN, the SmtpClient.Send function throws SmtpException if authentication failed. That stinks because that same exception can mean various other things too. But it sounds like you want to verify the user name and password without sending an email. The SMTP protocol certainly allows that, but the SMTPClient class only provides methods for sending email. I don't know of any built-in .NET class that provides what you want.
So I think you need to either
Write your own SMTP code using TCP.
Find a third-party SMTP client that provides more functionality..
Send a dummy email to a dummy address, and look at the StatusCode property to see if there was an authentication problem.
Option number 1 is hard if you care about SSL. If you just use plain text, I think authenticating to SMTP isn't that hard. But more and more mail servers are forbidding that. Option 3 is a hack, but should be easy.
EDIT: Added details about the StatusCode property.
The SMTPClient's Send(MailMessage) method raises a SmtpFailedRecipientsException exception if one or more recipient
addresses were incorrect or unreachable.
Sample Code :
try
{
smtpClient.Send(new MailMessage("test#test.com", "test#test.com", "test", "test"));
return string.Empty;
}
catch (SmtpFailedRecipientException)
{
return string.Empty;
}
catch (Exception ex)
{
return string.Format("SMTP server connection test failed: {0}", ex.InnerException != null ? ex.InnerException.Message : ex.Message);
}
When authenticating, store the username and password in the session. Compare the values of the session with user entries . If bool==true then send the email or else dont.
i have few question about smtp
im using this code to send mails if the host is gmail then it act diffrente:
foreach (string host in hosts)
{
SmtpClient sc = null;
try
{
if (emailDomain.ToLower() == "gmail.com")
{
MailSend.MailSendApp.EventLog.WriteEntry("mail to gmail.com");
sc = new SmtpClient("smtp.gmail.com", 587);
sc.UseDefaultCredentials = false;
sc.DeliveryMethod = SmtpDeliveryMethod.Network;
sc.Credentials = new NetworkCredential("UID#gmail.com", "PWD");
sc.EnableSsl = true;
} }
else
{
sc = new SmtpClient(host);
sc.Send(mailMessage);
break;
}
is it possiable to get answer from smtp :
1. that the email arrived
2. if the mail exists
thanks
If you want to receive a notification that the email has arrived you need to send the email with delivery notification options.
mailMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
If the email doesn't exists, you will get an email back to your sender address and not to your SMTP class.
In short, there's no easy way to determine these two thing purely from the SMTP class perspective.
Back in the day you could directly query whether the email address exists on a given server (VRFY user SMTP command). Then, SPAM was born and pretty much all email servers removed that capability because spammers would use bots to query possible email recipients on each mail server to build SPAM lists.
You will still get an ordinary bounce report (email back to the reply-to address indicating that delivery failed). I use a tool called Boogie Tools to automate processing of bounce messages.
Gmail does not offer delivery or read receipts (though some email servers still optionally allow it) for similar reasons... too much abuse potential.
I have a small email application that lets a user build a message from checkboxes and then send the message as an email. I am trying to add an image to the email, i.e. a logo or signature. The application worked fine but as I was reseaching getting the images into the email, I found that I should be using System.Net.Mail instead of Interop. So I changed my email class to the code below. Now I'm not recieving the emails. I'm assumeing this is because the code is set-up for a server and I just want to run this on my local machine. This is just something I'm playing with to help me understand some concepts so real world use is not going to be a factor. I just want to be able to test my little program on my Outlook email account locally. My code is as follows...
using System;
using System.Net.Mail;
using System.Net.Mime;
namespace Email_Notifier
{
public class EmailSender:Notification
{
string emailRecipient = System.Configuration.ConfigurationManager.AppSettings ["emailRecipient"];
public void SendMail(string message)
{
try
{
string strMailContent = message;
string fromAddress = "MyApp#gmail.com";
string toAddress = emailRecipient;
string contentId = "image1";
string path = (#"C:Libraries/Pictures/Logo.gif");
MailMessage mailMessage = new MailMessage(fromAddress, toAddress);
mailMessage.Subject = "Email Notification";
LinkedResource logo = new LinkedResource( path , MediaTypeNames.Image.Gif);
logo.ContentId = "Logo";
// HTML formatting for logo
AlternateView av1 = AlternateView.CreateAlternateViewFromString("<html><body><img src=cid:Logo/><br></body></html>" + strMailContent, null, MediaTypeNames.Text.Html);
av1.LinkedResources.Add(logo);
mailMessage.AlternateViews.Add(av1);
mailMessage.IsBodyHtml = true;
SmtpClient mailSender = new SmtpClient("localhost");
mailSender.Send(mailMessage);
}
catch (Exception e)
{
Console.WriteLine("Problem with email execution. Exception caught: ", e);
}
return;
}
}
}
You specify mailSender = new SmtpClient("localhost");.
Have you set up an SMTP server on your local machine? If not, you will need to do so to use SmtpClient. Otherwise, specify a hostname other than localhost, perhaps using your Gmail account as specified here, bearing in mind you will need to configure it for authentication and SSL.
See also the documentation for SmtpClient.
There are also one or two other issues I can see with your code - but let's deal with these after getting simple mail sending working.
if your problem is that you don't have a smtp server you are talking to on your machine, you will see an exception rather than just silently not having your email delivered (which i believe is what you are seeing given that you did not list an exception, but not completely sure). it could be that you are successfully delivering to your local smtp server, but it is failing to send the mail on. if you have the iis smtp server installed and that is what you are trying to use to send the mail, you can see failed email messages in the subdirectories of C:\Inetpub\mailroot. there is a badmail subdirectory that should have failed deliveries.
if you are on windows 7, it doesn't support the iis smtp server. an alternative for having an smtp server on your machine that doesn't actually deliver the email but does show you everything that has come through for any email address is http://smtp4dev.codeplex.com/. even if i do have the iis smtp server available in my operating system, i prefer this for development needs.