Web Server is Sending Duplicate E-Mails - c#

For every e-mails that my website sends I have it send myself an email as well. I noticed that about 5% of the e-mails (Thousands a day) are being sent twice. The time between the duplicates being sent however is completely inconsistent...Can be a week, a month or a minute. Completely inconsistent...I've tried to debug the issue but I can never duplicate the issue. Always just sends one e-mail and works properly. I'm out of ideas so decided to try and gain some input form the community. Any insight would be greatly appreciated...
public static void SendEmail(string subject, string body, string toAddress, string fromAddress)
{
MailMessage msg = new MailMessage();
msg.From = new MailAddress(fromAddress);
msg.To.Add(new MailAddress(toAddress));
msg.Subject = subject;
msg.Body = body;
msg.IsBodyHtml = false;
using (SmtpClient cli = new SmtpClient())
{
cli.Send(msg);
cli.Dispose();
}
}
Dispose() was just one of my recent attempts that have failed to fix the problem....
And the ascx page that calls the function (note that it is called twice to send it to myslef the first time and the customer the second time if there e-mail address is not null. I did this during testing and decided to leave it in there:
Txp.SendEmail(strOrderConfirmationHeader, strOrderConfirmationText, TxpConst.ORDERNOTIFYADDR, TxpConst.RETURNADDR);
if (!String.IsNullOrWhiteSpace(custemail))
{
Txp.SendEmail(strOrderConfirmationHeader, strOrderConfirmationText, custemail, TxpConst.RETURNADDR);
}
The fact that it's so inconsistent tells me it's probably not the code and it's not the e-mail server cause the mail logs show a completed transaction every time and it gets a different message id every time...I'm all out of ideas!

OK, I'm sure you've already considered this, but are you sure your visitor isn't hitting "submit" twice?
I've seen this many times, particularly when the email server is running a little slowly. User thinks the site isn't doing anything so clicks Submit again. (Or they just double-click the button - seen that too!)
You might just need to put some code your app to guard against multiple submission. It's a fairly common issue.
Hope this helps you.

Related

Office 365 Exchange SMTP intermittent authentication failure in .NET application

We have a number of C# (.net 4) apps that send email via our Office 365 Exchange account. This works absolutely fine 90% of the time. But sporadically we get the following error:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM.
Here is the code:
private void SendEmail(string strTo, string strFrom, string strMessage, string strSubject, bool htmlFormat = true)
{
System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
System.Net.Mail.MailAddress mto = new System.Net.Mail.MailAddress(strTo);
System.Net.Mail.MailAddress mfrom = new System.Net.Mail.MailAddress(strFrom);
mail.Subject = strSubject;
mail.From = mfrom;
mail.To.Add(mto);
mail.Body = strMessage;
mail.IsBodyHtml = htmlFormat;
System.Net.Mail.SmtpClient mailClient = new System.Net.Mail.SmtpClient("smtp.office365.com", 587);
mailClient.Timeout = 1000000;
mailClient.EnableSsl = true;
mailClient.UseDefaultCredentials = false;
mailClient.Credentials = new System.Net.NetworkCredential("my#emailaddress.com", "mypassword");
mailClient.Send(mail);
}
I've seen questions asked about this error message on here before, but I have not yet found any explanations as to why it might be happening only intermittently. The error message is confusing since I am not trying to send anonymously, and I am already using EnableSsl. (Note: if I remove the Credentials line or the EnableSSL line, then I get this error every time)
EDIT: As a test, I made a simple app that emails me 1 time per minute. I typically get between 12 and 25 successful emails before one blows up. Then it will go right back to normal for another 12-25, before blowing up again.
EDIT: Since the issue is so sporadic, and involves an error message returned from the 365 SMTP server, I don't really think its a problem with the code itself. Given that, I'm not sure if I've tagged the question properly, or if SO is even the best community for it. If any of you Stack Exchange veterans think this would be better placed in a different community, I am all ears. I'm a bit new here myself.
Any thoughts are appreciated!
I opened a case with Microsoft 365 support on this, and they told me I was not the only one experiencing the issue. They had me try capturing SMTP logs when the issue occurs, but we never found much of anything very helpful. The MS tech also stated that he was going to try upgrading something on our mail server on the back end (not sure what exactly). After he did that the problem was still occurring but seemed less frequent.
Eventually it became less and less frequent and now I have not seen it occur in about 5 days. So, I don't know that this is from anything specific that my MS tech did, or just a larger problem eventually getting solved. But for now, the problem seems to have gone away, and not by changing anything on our end.
public static void SendEmail(string sTo, string subject, string body)
{
var Port = int.Parse(ConfigurationManager.AppSettings["SmtpPort"]);
using (var client = new SmtpClient(Your EmailHost, Port))
using (var message = new MailMessage()
{
From = new MailAddress(FromEmail),
Subject = subject,
Body = body
})
{
message.To.Add(sTo);
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["EmailCredential"],
ConfigurationManager.AppSettings["EmailPassword"]);
client.EnableSsl = true;
client.Send(message);
};
}
After adding SMTP details properly in your email application
You need to go to on the > Microsoft 365 admin center (https://admin.microsoft.com) > Active users
Select a user you wish to authenticate with the SMTP server
Select the Mail Tab (See Image 1)
Under Email apps, Select> Manage email apps
Make sure that "Authenticated SMTP" checkbox is selected (See Image 2)
And save
Your email should work after that.
IMAGES EXAMPLES HERE
Image 1
Image 2

Sending multiple emails with transaction behavior (if one fails no emails get send)

Sorry if I failed to find an existing post with my problem.
What am I trying to do is as follows:
I simply want to send a couple of emails (2-3) to different people and more importantly with different content. The emails are official, important and also logged in the system. Long story short, I need when for some reason one of them fails to stop the sending of the others. I need either all of them sent or none of them.
What have I done so far
It is not the first time the system I worked on has to send an automatic email. The application is an ASP MVC website. So some time ago, I installed the MvcMailer (MvcMailer) and used it the way it was explained. It worked quite well and so I liked the idea of previewing the email (as you can give it a view to send).
So, in the light of my new problem I read carefully the MvcMailer documentation and did not find anything about sending multiple emails in transaction-like manner. Couldn't think of a way to force them to behave in this way. In my tests when I send an email, even if it is one email with a few CCs, all working mails get send and just one of them fails (wrong email name, closed port ... whatever).
I was hoping someone could suggest me a way to achieve something like this. I hope my explanation was sufficient and if not, let me know I will provide you with all details required.
If this is impossible with the MvcMailer, then is it possible with other tools ?
My implementation so far: (keep in mind I'm still in the testing stages)
public class MailerController : Controller
{
private MailerRepository mailerRep;
public MailerController()
{
this.mailerRep = new MailerRepository();
}
public void TestTransmittalEmail()
{
var model = this.mailerRep.GetTransmittalModel(1234); //I've stucked a specific clientId
var mailer = new TransmittalsMailer();
mailer.TransmittalEmail(model).Send();
}
}
public class TransmittalsMailer : MailerBase
{
public TransmittalsMailer()
{
}
public MvcMailMessage TransmittalEmail(TransmittalManifestModel model)
{
var mailMessage = new MvcMailMessage() { Subject = "Transmittals - TESTING EMAIL" };
//embedding a few images in the email
var resources = new Dictionary<string, string>();
resources["logo"] = PDFResourcePaths.VripackLogo;
resources["companyInfo"] = PDFResourcePaths.CompanyInfoBlock;
mailMessage.To.Add("test1#email.com");
mailMessage.Attachments.Add(new Attachment(#"D:\ASD\TransmittalFolders\1\Archives\150812.1433.MMA.rar"));
ViewData["model"] = model;
this.PopulateBody(mailMessage, "TransmittalEmailView", resources);
return mailMessage;
}
}
This is actually quite a difficult problem to solve. This is because when you send an email, it will work as long the SMTP server can be found (no exception will be thrown).
So you basically have to wait some arbitrary amount of time, and check the inbox of the email you sent it from for the delivery failure. If there is a delivery failure, you stop sending.
So long story short, you shouldn't probably do this. You should simply send all three and notify yourself some other way (probably another email) that there was a failure and which email failed.
You can check if an exception is thrown and then cancel the sending of subsequent emails until the issue is addressed. However this only deals with issues on your end on the sending of each email individual email. If the first two mails are successfully sent, and the last throws an exception, you can't unsend the first emails.
A possible workaround (ugly as it is) would be to initially send emails to an email address you control. If an exception is thrown at this step, log the error, and do not send any further emails until the error is dealt with. If no exceptions are raised, send the emails. However this does not and cannot handle issues that may occur on the recipients side.
A delivery failure notice is not guaranteed as depending on the configuration of your SMTP and the recipient SMTP a delivery failure notification might not be sent. Even if delivery failure notifications are enabled, the notification might not be sent for days (in one of my previous jobs, email delivery failure notifications were not sent until 14 days had elapsed).
Ideally, this should be dealt with at the initial input of the email addresses before you ever send any documents to anyone. You simply send a verification email to the email address in question and have the user clicking on a verification link back to a web service you control. Until this has been done, you don't send any emails to the intended recipient.

how to send email in C# even when one of the recipient is invalid?

I am trying to send email to multiple recipients and it works fine when all the recipients have valid email address.
But when one of the recipients have invalid email address, email is not sent even to other recipients whose email address is valid and I am getting an exception:
The server rejected one or more recipient addresses. The server
response was: 550 #5.1.0 Address rejected.
Is there any way I can send the email to other valid recipients even if one of the email address is invalid?
public static void sendMails(string ptxtSubject, string ptxtBody)
{
string txtTo = "valid1#aaa.com,valid2#aaa.com,invalid1#aaa.com";
string txtFrom = "valid#aaa.com";
string txtSubject = ptxtSubject;
string txtBody = ptxtBody;
MailMessage mail = new MailMessage();
mail.To = txtTo;
mail.From = txtFrom;
mail.Subject = txtSubject;
mail.Body = txtBody;
try
{
SmtpMail.SmtpServer ="smtp.aaa.com";
SmtpMail.Send(mail);
}
catch (Exception ex)
{
//log the exception
throw;
}
}
I can send separate mail to each of them but users(recipients) will not know who else is in the email distribution list. My requirement is everyone should be able to know who else is receiving the email.
Outlook sends the email to all the valid users and notifies us back of invalid users. Is there anyway we can do the same using C#?
Unless all the recipients definitely know each other (and they don't mind other people knowing they are receiving email from you), you should be sending separate emails anyway.
This would also take care of your problem, i.e. if one send operation fails, it won't disrupt the others. Note that in your case, it appears that the initial relay is failing because the addresses are from the same host as the SMTP server.
Once an email is routed to multiple hosts, the success/failure is no longer interdependent. For example, a gmail.com server probably doesn't know/care that a yahoo.com server rejected a recipient.
If performance is a concern, you can send the messages asynchronously to get achieve better throughput. Note that you can still handle exceptions when sending asynchronously.
As always, if you are sending any quantity of email, it's probably advisable to use a 3rd party service.
I really don't see any way to accomplish this. Sending an email with SmtpMail.Send() is pretty much an atomic function and you need correct data for it to work without an exception.
The only option I see here is to send separate emails to each recipient.

sending multiple emails with mvcmailer

Im looking to use MVCMailer to send emails using asp.net mvc 3 with razor. Also mentioned by ScottHa
It looks fairly straight forward, however i'm confused as to how I would send batch emails eg like a newsletter to a list of users.
do i create a loop around this?
public virtual MailMessage Welcome()
{
var mailMessage = new MailMessage{Subject = "Welcome to MvcMailer"};
mailMessage.To.Add("sohan39#example.com");
ViewBag.Name = "Sohan";
PopulateBody(mailMessage, viewName: "Welcome");
return mailMessage;
}
can someone explain?
thanks
Unfortunately because each email message is personalized, I can't see any other way other than looping. So just change your method to something like:
public virtual MailMessage Welcome(string email, string name)
{
var mailMessage = new MailMessage{Subject = "Welcome to MvcMailer"};
mailMessage.To.Add(email);
ViewBag.Name = name;
PopulateBody(mailMessage, viewName: "Welcome");
return mailMessage;
}
And then call that method inside your loop and send it at the same time.
Important Note
You should setup your web.config to use a pickup directory rather than a SMTP server. Then get IIS to send the email from the pickup directory.
Reasoning - Because you could potentially be calling SmtpClient.Send(MailMessage mailmessage) any number of times - this could become rather expensive if you have to connect to a SMTP server each time to send the email.
A nice side effect of this is you also get some redundancy if the SMTP server is down or unreachable for any reason.
If you want different content for each email, you'll need to create individual MailMessage objects using a loop. If you want the same contents, then you can just add multiple recipients:
mailMessage.To.Add("sohan39#example.com");
mailMessage.To.Add("peter23#example.com");

Email messages going to spam folder

I have created a community portal, in which user creates his/her account. After successfull registration a confirmation mail is send on registered email address.
I am using the following code to send the mail -
private void SendMail(string recvr, string recvrName, string verCode, int NewUserID)
{
try
{
string emailID = ConfigurationManager.AppSettings["WebMasterMail"];
string mailPass = ConfigurationManager.AppSettings["pass"];
string mailer = ConfigurationManager.AppSettings["mailer"];
MailMessage msg = new MailMessage();
MailAddress addrFrom = new MailAddress(emailID, "Panbeli.in.... Bari community portal");
MailAddress addrTo = new MailAddress(recvr, recvrName);
msg.To.Add(addrTo);
msg.From = addrFrom;
msg.Subject = "You have registered sucessfully on PanBeli.in.";
msg.Priority = MailPriority.High;
msg.Body = RegisterMessageBody(recvrName, verCode,NewUserID);
msg.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient(mailer);
smtp.Credentials = new System.Net.NetworkCredential(emailID, mailPass);
smtp.Send(msg);
}
catch (Exception Ex) { }
}
While testing we found that all the confirmation mails are going to SPAM folder instead of Inbox.
Is there anything wrong with the code or is there anything related to security.
Can anybody suggest solution to this problem.
Thanks for sharing your time.
It sounds like your email is getting flagged by SpamAssassin or the like, so you just need to focus on changing your email enough to not get flagged.
Your content doesn't sound like it has any reason to rate high for the Bayesian score, so I don't think thats the problem. It wouldn't hurt to try removing possible trigger words though.
Your message is marked with high priority. Do you need this? This just adds into one of the scoring metrics in a spam filter. Spam is often marked with high priority, so your message will be treated with more scrutiny. On the otherhand, for some filters marking your message with high priority will mean less scrutiny.
IsBodyHTML is marked true, but you're only providing text/html. You minimally need to include an alternate view with text/plain.
message.IsBodyHtml = true;
string html = RegisterMessageBodyHtml(recvrName, verCode,NewUserID);
string plain = RegisterMessageBodyPlaintext(recvrName, verCode, NewUserID);
message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, new ContentType("text/html"));
message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(plain, new ContentType("text/plain"));
See how Google treats your message. In gmail, open a test message that you've sent, click the downfacing arrow next to the reply button, and select "Show Original". You'll see how Google treated your message. Look for headers like:
Received-SPF: softfail (google.com: domain of transitioning xxx#xxx.org does not designate xx.xx.xx.xx as permitted sender) client-ip=xx.xx.xx.xx;
Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning xxx#xxx.org does not designate xx.xx.xx.xx as permitted sender)
Read up on the default rule set for SpamAssassin as it will probably be a good reference on the rule sets for most filters. If you can identify why your message is getting flagged, you can fix it.
Emails Marked as Spam
This is not a programming issue unfortunately, but I can understand why you might think it is. The code is sending the emails, and they have been sent as you reported. So this is highly unlikely to be a problem with your code, because it's served it's purpose fully!
Getting around it
It all comes down to the recipients mail client (the software they are using to view the emails with), or the services that process the emails at some sort of gateway, or a combination of both of these!
All of these elements have vastly varied algorithms and metrics for determining if an email is probably spam or not. So a one fit all solution is sadly not possible. Some are intelligent, other less so, some brutally discard a huge % of emails, others operate purely on a 'not on white list, you're not getting in' policy, and then there are those that just let everything come in regardless of content/origin.
The ways to go around fixing this are:
To try and get on white lists for major email providers.
Educate your audience to add the senders email address as a trusted contact.
Check your mail server IP isn't blacklisted by some providers. It's possible your IP address was previously used to send spam.
Experiment with the emails content
Your from address is invalid. Try putting in a real email address that points to a valid mailbox. Preferably this email address is on the same domain as the SMTP server you use to send the mail with. If not, read into SPF http://en.wikipedia.org/wiki/Sender_Policy_Framework
This happen to me to and it's solved now,
I just set the BodyEncoding and SubjectEncoding proprieties on the MailMessage object,
and added the DOCTYPE and the html tags to my email header,
var msg = new MailMessage
{
Subject = subject,
Body = body,
BodyEncoding = System.Text.Encoding.UTF8,
SubjectEncoding = System.Text.Encoding.Default,
IsBodyHtml = true
};
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
It's working perfectly now
Add following line in your code while creating MailMessage
msg.BodyEncoding = System.Text.Encoding.GetEncoding("utf-8");
This happens a lot even for the house hold names. I sympathise with you as you only want a plain text email but if your clients really want those emails and you really want your logo in then they could just white list your domain so that all emails get through!
We use a company called mailchimp for sending out subscriber mails and I questioned them on how to avoid spam filters especially in the context of essentially an advert out to a large group it can be very difficult to avoid them, here is their advice and there is lots of it.;
Avoiding the Spam Filters
For anyone having this problem, it looks like Google mark as spam any mails using the default ASP.NET e-mail authentication subject and body. I.e.:
"Please confirm your account by clicking here."
Changing the text allows the e-mail to pass the spam filter

Categories