I am building a ecommerce site and after a purchase is done, I want to send the buyer an email first before I commit my database changes but somehow, the send failure rate is about 25 - 30 percent. I am using hotmail current as a temp email account, not sure if it's hotmail's issue, anyway this is my code, any advice? Thanks:
Code:
MembershipUser u = Membership.GetUser(HttpContext.Current.User.Identity.Name);
AccountProfile usercustomProfile = new AccountProfile();
var p = usercustomProfile.GetProfile(u.UserName);
MailMessage mail = new MailMessage();
mail.To.Add(u.Email);
mail.IsBodyHtml = true;
mail.From = new MailAddress("XXX#hotmail.com");
mail.Subject = ("Purchase invoice" + ' ' + newOrder.OrderID);
string mailBodyHeader =
"<table border=0> <tr> <td>Product ID</td><td>Model Number</td><td>Model Name</td><td> Unit Cost</td> <td>Quantity</td><td>Price</td></tr>";
System.Text.StringBuilder bodyContent = new System.Text.StringBuilder();
double unitQtyPrice = 0;
double totalPrice = 0;
foreach (var cItem in cartList)
{
unitQtyPrice = cItem.Quantity * (double)cItem.UnitCost;
totalPrice += unitQtyPrice;
bodyContent.Append("<tr>");
bodyContent.Append("<td>");
bodyContent.Append(cItem.ProductID.ToString());
bodyContent.Append("</td>");
bodyContent.Append("<td>");
bodyContent.Append(cItem.ModelNumber.ToString());
bodyContent.Append("</td>");
bodyContent.Append("<td>");
bodyContent.Append(cItem.ModelName);
bodyContent.Append("</td>");
bodyContent.Append("<td>");
bodyContent.Append(Math.Round(cItem.UnitCost, 2));
bodyContent.Append("</td>");
bodyContent.Append("<td>");
bodyContent.Append(cItem.Quantity.ToString());
bodyContent.Append("</td>");
bodyContent.Append("<td>");
bodyContent.Append("$" + Math.Round(unitQtyPrice, 2));
bodyContent.Append("</td>");
bodyContent.Append("</tr>");
}
Math.Round(totalPrice, 2);
mail.Body = "Thanks you for shopping with XXX. Your purchase details are as follow:"
+ "<br><br>" + "Name:" + p.FirstName + p.LastName
+ "<br>" + "Mailing Address:" + p.MailingAddress
+ "<br>" + "Billing Address:" + p.BillingAddress
+ "<br>" + "Contact No.:" + p.Contact
+ "<br><br>" + mailBodyHeader + bodyContent.ToString() + "</table>"
+ "<br>" + "Total Price:" + "$" + totalPrice
+ "<br>" + "Additional / Special instructions:"
+ "<br>" + SInfo
+ "<br><br>" + "Please blah blah blah";
SmtpClient client = new SmtpClient("smtp.live.com", 587);
client.EnableSsl = true; //ssl must be enabled for Gmail
NetworkCredential credentials = new NetworkCredential("XXX#hotmail.com", "ABCDE");
client.Credentials = credentials;
//Sends a message to from if email is not deliverable
mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
//Create the SMTPClient object and DO NOT specify the SMTP server name, it’s being pulled from config file
SmtpClient SMTPServer = new SmtpClient();
SMTPServer.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
try
{
client.Send(mail);
db.SaveChanges();
}
catch (SmtpException)
{
Server.Transfer("/CheckOutUnsuccessful.aspx", true);
}
}
return (true);
}
If you are using SQL Server on the backend you can set the database server up to handle the mail requests. The advantage of using SQL Server as opposed to ASP.NET code is the database can be configured to retry sending the messages several times on failure.
Here is a good resource on how to configure Database Mail: http://blog.sqlauthority.com/2008/08/23/sql-server-2008-configure-database-mail-send-email-from-sql-database/
Related
I have a support ticket web application, very old, done in ASP.NET webforms
Until 5 October 2021 it has worked perfectly, then has started to miss, sometimes to send out emails.
In the last few days has started to miss sending out most of the emails.
I'm using office365.com as SMTP and POP3 server. POP3 has never given any issue.
I'm using the same account for sending and for reading.
The workload is very very low: I read the POP3 every 5 minutes, and I send out emails just to confirm we have taken in charge the request. And we are talking about 1 email every 1~2 hrs, therefore is not a heavy workload.
This is the code:
private static string sSMTP = "smtp.office365.com";
private static string sPOP3 = "outlook.office365.com";
private static string sEmailAddress = "sender-email#domain.com";
private static string sEmailAccount = "sender-email#domain.com";
private static string sEmailName = "ACME";
private static string sPassword = "SomePassword";
SendMailConfirm("test.user1#gmail.com", "this is a test", "" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"), 1);
SendMailConfirm("test.user2#some-domain.com", "this is a test", "" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"), 1);
SendMailConfirm("test.user2#another-domain.com", "this is a test", "" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"), 1);
private void SendMailConfirm(string sTo, string sSubj, string sBody, int iCallID)
{
SmtpClient client = new SmtpClient(sSMTP);
//authentication
client.Credentials = new System.Net.NetworkCredential(sEmailAccount, sPassword);
client.EnableSsl = true;
client.Port = 587; //tried also 25 with same result.
MailAddress from = new MailAddress(sEmailAddress, sEmailName);
MailAddress to = new MailAddress(sTo);
MailMessage message = new MailMessage(from, to);
message.Subject = sSubj;
message.ReplyTo = new MailAddress("no-reply#domain.com");
message.Body = "Dear user your support ticket has been inserted.\r\n " +
"Request ID: " + iCallID.ToString() + ".\r\n\r\n-----------------\r\n" + sBody;
SendMessage(client, message);
}
private void SendMessage(SmtpClient client, MailMessage message)
{ // here I've tried to add some delay and see what happen but I always get randomly, 90% of the time "Failure sending mail" as exception.
try
{
client.Send(message);
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " 1st message to " + message.To + " succesfully sent!!!!!!!!!!!!!! ";
}
catch (Exception ex)
{
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " 1st message to " + message.To + " " + ex.Message + "<hr/>"+ex.StackTrace+"<hr/>";
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " -> retry in 1500ms.";
try
{
Thread.Sleep(1500);
client.Send(message);
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " 2nd message to " + message.To + " succesfully sent!!!!!!!!!! ";
}
catch (Exception ex2)
{
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " 2nd message to " + message.To + " " + ex2.Message;
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " ---> retry in 3000ms.";
try
{
Thread.Sleep(3000);
client.Send(message);
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " 3rd message to " + message.To + " succesfully sent!!!! ";
}
catch (Exception ex3)
{
output.Text += "<br/>" + DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss") + " 3rd message to " + message.To + " " + ex3.Message;
}
}
}
message.Dispose();
}
The same code works perfectly fine using another email provider, but not on SendGrid or Gmail.
Which could be the cause?
Is there any way to get a more talking message error from SMTP?
After several tries, I've found that the issue is in the System.Net.Mail object of the .Net framework.
I've also found that Microsoft strongly suggest to not use it!:
https://learn.microsoft.com/en-gb/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.8
We don't recommend that you use the SmtpClient class for new development because SmtpClient doesn't support many modern protocols. Use MailKit or other libraries instead. For more information, see SmtpClient shouldn't be used on GitHub.
After testing it also with SendGrid I've obtained the same behaviour.
Therefore the only solution is to move to MailKit
I've made the code changes, to send the message out with MailKit, and after hundreds of tries, it has never failed.
I need to send attachment with email. I used following code which gives below exceptions.
System.NullReferenceException: Object variable or With block variable
not set. at
Microsoft.VisualBasic.CompilerServices.Symbols.Container..ctor(Object
Instance) at
Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object
Instance, Type Type, String MemberName, Object[] Arguments, String[]
ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack) at
dynamicPage.makeCustom_Click(Object sender, EventArgs e)
try {
generateRequestID();
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient();
mail.To.Add("email.text");
mail.From = new MailAddress(personEmail.Text);
mail.Subject = "IDFC Bank BrandStore Product Customization Request";
mail.Body = "Request ID : " + Session["requestID"].ToString + "<br>Name : " + personName.Text + "<br>Contact : " + personContact.Text + "<br>Email : " + personEmail.Text + "<br>Department : " + Department.Text + "<br>Quantity : " + quantity.Text + "<br>Description : " + customDescription.Text + "<br>Timeline : " + customTimeline.Text + "<br>Product Link : " + Request.Url.AbsoluteUri + "";
if (artworkContainer.HasFile) {
string FileName = Path.GetFileName(artworkContainer.PostedFile.FileName);
mail.Attachments.Add(new Attachment(artworkContainer.PostedFile.InputStream, FileName));
}
mail.IsBodyHtml = true;
SmtpServer.Port = 25;
SmtpServer.Credentials = new System.Net.NetworkCredential("you#yourdomain.com", "mypassword");
SmtpServer.Host = "relay-hosting.secureserver.net";
SmtpServer.EnableSsl = false;
SmtpServer.Send(mail);
Response.Redirect("/customization-request-sent");
} catch (Exception ex) {
Response.Write(ex);
}
I have a C# Winforms application I'm working on in Visual Studio 2010, the page in question is a bug reporting form - I have all the details set, email sends fine etc. My issue is attaching a screenshot to the email in the body, I have code set up to allow users to find and select a screenshot they take and attach to the form, but in the body itself it just gives me the text "System.Windows.Forms.Picturebox", or various similarities to that if I try .image.
I've had a look around via Google and here, but can only find topics that are to do with embedding the image or attaching it (and thus require to enter in a specific folder/image etc), whereas my users will be attaching their own image and name from different places. Is there anyway to get the image to be picked up without having to hardcode a location and name that my users will have to follow each time?
Code below:
private void btnBugEmail_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
try
{
SmtpClient client = new SmtpClient("details here");
MailMessage message = new MailMessage();
message.From = new MailAddress("email here");
string mailBox = txtBugAdd.Text.Trim();
message.To.Add(mailBox);
string mailFrom = txtEmailFromBug.Text.Trim();
message.CC.Add(mailFrom);
string mailCC = txtMailCCBug.Text.Trim();
message.Bcc.Add(mailCC);
message.IsBodyHtml = true;
message.Body = "Bug Report - please see below: " +
"\n" + "<br>" + "<b>" + "1. What were you doing at the time of the error?" + "</b>" +
"\n" + "<br>" + rtbTimeOfError.Text +
"\n" + "<br>" + "<b>" + "2. Are you able to repeat the steps and achieve the same error?" + "</b>" +
"\n" + "<br>" + rtbCanRepeat.Text +
"\n" + "<br>" + "<b>" + "3. Does this problem happen again if you change any of the details you have entered?" + "</b>" +
"\n" + "<br>" + rtbChangeDetails.Text;
message.Subject = "Bug Report";
var image = pboxBugImage.Image;
using(var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Jpeg);
message.Attachments.Add(new Attachment(ms, "Screenshot.jpg"));
client.Credentials = new System.Net.NetworkCredential("credentials here");
client.Port = System.Convert.ToInt32(25);
client.Send(message);
}
new Endpage().Show();
this.Close();
}
catch
{
MessageBox.Show("my comment here");
}
}
Take a look to the following link
system.net.mail.mailmessage.attachments
You cannot put a winforms control inside the mailmessage :) it is outputted with ToString()... that is what you see in mail
Example
private void btnBugEmail_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
try
{
SmtpClient client = new SmtpClient("details here");
MailMessage message = new MailMessage();
message.From = new MailAddress("email here");
string mailBox = txtBugAdd.Text.Trim();
message.To.Add(mailBox);
string mailFrom = txtEmailFromBug.Text.Trim();
message.CC.Add(mailFrom);
string mailCC = txtMailCCBug.Text.Trim();
message.Bcc.Add(mailCC);
message.IsBodyHtml = true;
message.Body = "Bug Report - please see below: " +
"\n" + "<br>" + "<b>" + "1. What were you doing at the time of the error?" + "</b>" +
"\n" + "<br>" + rtbTimeOfError.Text +
"\n" + "<br>" + "<b>" + "2. Are you able to repeat the steps and achieve the same error?" + "</b>" +
"\n" + "<br>" + rtbCanRepeat.Text +
"\n" + "<br>" + "<b>" + "3. Does this problem happen again if you change any of the details you have entered?" + "</b>" +
"\n" + "<br>" + rtbChangeDetails.Text;
message.Subject = "Bug Report";
var image = pboxBugImage.Image;
using(var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Jpeg);
message.Attachments.Add(new Attachment(ms, "Screenshot.jpg"));
client.Credentials = new System.Net.NetworkCredential("credentials here");
client.Port = System.Convert.ToInt32(25);
client.Send(message);
}
new Endpage().Show();
this.Close();
}
catch
{
MessageBox.Show("my comment here");
}
}
Take a look at your resources and dispose the memorystream. I didnt for the example, because i wrote it here in editor
I have written a code which sends mail to the admin for moderation whenever a user adds a content from front end.....the problem is sometimes the admin gets two mails of same content.
below is my code
MailMessage mail = new MailMessage();
string mailto = ConfigurationManager.AppSettings["adminStoryEmail"].ToString();
mail.To.Add(mailto);
//mail.To.Add("vidyasagar.patil#viraltech.in");
mail.From = new MailAddress(ConfigurationManager.AppSettings["fromEmail"]);
mail.Subject = ConfigurationManager.AppSettings["email_subject"];
if (uploadedpath != "")
{
mail.Body = "Email ID : " + txtEmail.Text + "<br /> Title : " + txtStoryTitle.Text + "<br />" + " Download : " + " http://www.achievewithdell.in/uploads/" + uploadedpath + "<br />";
if (story != "")
{
mail.Body += "New story has been added" + " http://www.achievewithdell.in/admin/ManageStory.aspx";
}
}
else
{
mail.Body = "Email ID : " + txtEmail.Text + "<br /> Title : " + txtStoryTitle.Text + " <br />";
if (story != "")
{
mail.Body += "New story has been added" + " http://www.achievewithdell.in/admin/ManageStory.aspx";
}
}
mail.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host = ConfigurationManager.AppSettings["smtp_host"]; //Or Your SMTP Server Address
smtp.Port = 25;
smtp.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["smtp_userid"], ConfigurationManager.AppSettings["smtp_password"]); //Or your Smtp Email ID and Password
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Send(mail);
You say sometimes the email gets sent twice. This would suggest the code you've given us is fine, the problem probably lies with what calls that code.
One way you could eliminate duplicates is to queue up your mails to be sent, perhaps in a database (storing: to, from, subject, body etc). Then periodically, iterate through mails to be sent, ignoring duplicates and marking sent mails so they don't get sent again.
Failing a refactor to your application like that, as the other poster suggested, get out your debugger and set a breakpoint. Depending on your version of Visual Studio, you could use the Breakpoint Hit Count so you only land at the breakpoint on the 2nd time.
Debug and make sure smtp Send() method is not called twice, put a break point on that line.
i had a problem in format in email. I want to have a new line..
here's the format in email..
Name: sdds Phone: 343434 Fax: 3434 Email: valencia_arman#yahoo.com Address: dsds Remarks: dsds Giftwrap: Yes Giftwrap Instructions: sdds Details: PEOPLE OF THE BIBLE(SCPOTB-8101-05) 1 x Php 275.00 = Php 275.00 Total: Php275.00
here's my C# code..
mail.Body = "Name: " + newInfo.ContactPerson + Environment.NewLine
+ "Phone: " + newInfo.Phone + Environment.NewLine
+ "Fax: " + newInfo.Fax + Environment.NewLine
+ "Email: " + newInfo.Email + Environment.NewLine
+ "Address: " + newInfo.Address + Environment.NewLine
+ "Remarks: " + newInfo.Notes + Environment.NewLine
+ "Giftwrap: " + rbGiftWrap.SelectedValue + Environment.NewLine
+ "Giftwrap Instructions: " + newInfo.Instructions + Environment.NewLine + Environment.NewLine
+ "Details: " + Environment.NewLine
+ mailDetails;
If you're sending it in HTML, make sure you set the format.
mail.BodyFormat = MailFormat.Html;
And then you can use <br/> should you want to.
UPDATE:
Try this as an alternative:
using System.Net.Mail;
...
MailMessage myMail;
myMail = new MailMessage();
myMail.IsBodyHtml = true;
maybe you can try this...
We create seperate email templates (e.g. EmailTemplate.htm), it includes the message to be sent. You will have no problems for new line in message.
Then this is our Code behind:
private void SendEmail()
{
string emailPath = "../EmailTemplate.htm"; //Define your template path here
string emailBody = string.Empty;
StreamReader sr = new StreamReader(emailPath);
emailBody = sr.ReadToEnd();
sr.Close();
sr.Dispose();
//Send Email; you can refactor this out
MailMessage message = new MailMessage();
MailAddress address = new MailAddress("sender#domain.com", "display name");
message.From = address;
message.To.Add("to#domain.com");
message.Subject = "Your Subject";
message.IsBodyHtml = true; //defines that your email is in Html form
message.Body = emailBody;
//smtp is defined in web.config
SmtpClient smtp = new SmtpClient();
try
{
smtp.Send(message);
}
catch (Exception ex)
{
//catch errors here...
}
}
Did you try "+\n" instead of Environment.NewLine?