The objective is to send automated emails to which of whom come from the results of my LINQ to SQL script. As I am not sure on ‘automated’ stuff I was going to approach this in the aspect of having a field in the table that the results are taken from change after the emails have been sent i.e. obj.EmailSent = true; - So that everytime the admin homepage is loaded it isnt sending it out again (eliminating duplication).
From that I would have to create a method to detect a new year and upon that reset all entries of the EmailSent field in the DB table to ‘false’, but for now its just the initial problem thats causing confusion.
I was going to opt for a ‘foreach’ solution so that all the recipients, individually, get their emails and not all together. Its the ‘foreach’ I’m not sure on as well as setting all the results collected to the new value of ‘EmailSent’ to ‘true’.
Here is my attempt:
C#:
protected void Page_Load(object sender, EventArgs e)
{
AdminUser user = AdminUser.GetCurrentUser();
if (user == null)
{
Response.Redirect("~/Login.aspx");
}
//Automated Birthday Emails
CheckAndSendEmail();
}
private void CheckAndSendEmail()
{
DataClassesBookingSysDataContext db = new DataClassesBookingSysDataContext();
var values = from p in db.ResBDayDiscounts
where p.DateofBirth.Value.Month == DateTime.Now.Month && p.DateofBirth.Value.Day == DateTime.Now.Day && p.EmailSent == false
select p;
foreach (var customers in values)
{
MailMessage msg = new MailMessage();
msg.From = new MailAddress("email_is@notreal.com");
msg.To.Add(new MailAddress(customers.Email.ToString()));
msg.Subject = "Happy Birthday" + customers.Forename.ToString() + "! Get your Special Birthday Discount from us now! ";
msg.Body = "message here";
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient();
client.Host = "smtp.email.com";
client.Credentials = new System.Net.NetworkCredential
("email_is@notreal.com", "password");
client.EnableSsl = true;
client.Send(msg);
customers.EmailSent = true;
db.SubmitChanges();
}
}
Great. Glad it is sorted. I would still suggest you do what I mentioned about the IisPickupDirectory. It will help with your apps performance, if its not critical to know that it was processed. For sending newsletters, etc. The app will then just drop the mail into a direcotory and carry on, then IIS will pick it up and send it when its ready, and your app does not have to wait for IIS to send it.
Ok after all that, I’ve solved it - something which may annoy some of u, it did me lol - very small
I wasnt assigning the DOB value to the EmailSent field in the table - now that I changed it to a dateTime datatype. In addition, because I hadn’t done that, it wasnt updating the field afterwards.
Thanks for all your help and if anything we now have a refined method, querying emailsent as a datetime and the ‘foreach’ updating it.
That sounds alot better. I’ll try that too, but does the foreach seem to look ok? as it won’t send the emails out when the page loads (being in the page load event)
To answer your original question, yes it does look ok. But I would rather use the query above to filter it out. Also, your smtp settings thould be in your web.config
I would not suggest letting SQL send the email. Yes, it would save resources from your app, but 90% of performance issues on websites are db bottle necks, so I would not put more load than needed on the SQL server.
To save some resourses on your site. Is to set your mail delivery method to IisPickupDirectory. Not exactly sure if that is right. But a quick google should give you all the info you need
Wouldn’t it be possibe to utilize a batch file here? Have it executed once per day and have SQL Server itself send the email? It would save resources on the app if it is possible.
Why not make EmailSent a DateTime instead of a bit. That way you can check if a birthday greeting was already sent this year. If so, don’t send it. If it was last year go ahead and send.
Then the query would look something like this:
var values = from p in db.ResBDayDiscounts
where p.DateofBirth.Value.Month == DateTime.Now.Month && p.DateofBirth.Value.Day == DateTime.Now.Day && p.EmailSent.Year != DateTime.Now.Year
select p;