How to know, that email was sent, and attachments can be deleted? - c#

I have a method, which saves screenshot by the definite path and then makes email message, attaching screenshot to it. As I've understood, after sending it - the special thread is being created in which attachment file is used, so I can't delete it while that thread is working. So, I need to know if when the file will be accessible for deleting.
Here's my code:
-- Configuring smtp
private SmtpClient CreateSMTP()
{
var smtp = new SmtpClient("gate");
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential("notifications#****.com", "3eCMCQxFde");
smtp.Port = 25;
smtp.EnableSsl = false;
return smtp;
}
-- Making message
public MailMessage MakeMessage(bool screenshotFlag)
{
MailAddress from = new MailAddress("notifications#****.com", Name);
MailAddress to = new MailAddress("****#****.com");
MailMessage message = new MailMessage(from, to);
message.Subject = Subject == string.Empty ? string.Empty : Subject;
message.Body = MessageText;
message.Body = GenerateLogAndExceptionInfo(message.Body);
message.BodyEncoding = Encoding.Unicode;
message.ReplyTo = new MailAddress(Mail);
if (screenshotFlag)
{
CreateScreenshot();
message.Attachments.Add(new Attachment(MailHelper.FeedBackScreenShotPath));
}
return message;
}
-- Sending email
public void SendMessage()
{
using (SmtpClient smtp = CreateSMTP())
{
smtp.Send(MakeMessage(SendWithScreenshot));
}
}

From the documentation:
These methods block while the message is being transmitted.
So while the message is being transmitted, the method blocks. So after the method is done and you've disposed the message instance, you could delete the file.
Of course, it could still have a lock on the file. That is why I would say you should first dispose the SmtpClient and then try to delete the file (so do that after the using block). It should be fine then.

I've seen that the file was holding by the message object, not by smtp object, so I added using block for message, too.
Thanks to all))

Related

How do you schedule an email in C# using Gmail?

So, this is my email function, that sends an email using Gmail's SMTP:
public void Email(string subject, string body)
{
try
{
MailMessage message = new MailMessage();
SmtpClient smtp = new SmtpClient();
message.From = new MailAddress(email, emailname);
message.To.Add(new MailAddress(targetemail, targetname));
message.Subject = subject;
smtp.EnableSsl = true;
message.IsBodyHtml = true;
message.Attachments.Add(new Attachment(folder + #"\" + cbPrezentacja.SelectedItem.ToString() + "." + extension));
message.Body = body;
smtp.Port = 587;
smtp.Host = "smtp.gmail.com";
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential(email, password);
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Send(message);
}
catch (Exception ex) {
MessageBox.Show(ex.ToString());
}
}
It works however, how would I schedule the email for a specific time? I don't mean making a Windows schedule/timer on the host (that requires leaving it on) or whatever, I want to do it via Gmail.
https://i.stack.imgur.com/eNG9D.png < This is how it works using Gmail. (sorry for the weird tint)
Is this even possible using System.Net.Mail or do I need a special Gmail API for that (if so, how?)? This is a private application for 1 computer, so it doesn't need to be super secure.
Thanks!
You can't.
There's nothing in SMTP to schedule it, when you do smtp.Send(message); the message is sent that exact moment.
Gmail has an API, but (as far I can see) it doesn't offer this functionality, so right now the only way to do it would be exactly what you say you don't want: your app should somehow wait till the desired time and send it.

Sending hardcoded email with attachment

I am trying to write a code for sending hard coded email with attachment i-e I don't want to use the buttons and text fields. I want when the program runs it should automatically go to location in my drive and attach some files and email it to the email address which I have already told that program while coding.
The normal code with buttons and text fields does not work. See below the normal code
MailMessage mail = new MailMessage(from.Text, to.Text, subject.Text, body.Text);
mail.Attachments.Add(new Attachment(attachment1.Text));
SmtpClient client = new SmtpClient(smtp.Text);
client.Port = 587;
client.Credentials = new System.Net.NetworkCredential(username.Text, password.Text);
client.EnableSsl = true;
client.Send(mail);
MessageBox.Show("Mail Sent!", "Success", MessageBoxButtons.OK);
I have tried replacing from.Text, to.Text, subject.Text, body.Text and attachment1.Text with a string as
string from="abc#gmail.com";
string attachment1=#"c:\image1.jpg";
They give me errors.
Remove the .Text after each variable, as strings don't have a Text property.
Like this:
MailMessage mail = new MailMessage(from, to, subject, body);

Save and send a mail using System.Net.Mail

I'm trying to send and save the send email using C# code. But i can't get this done. I can either save the mail, or send it. But i can't get both done.
This is what i have:
public ActionResult Index()
{
MailMessage message = new MailMessage();
message.From = new MailAddress("test#mail.com");
message.To.Add(new MailAddress("mymail#gmail.com"));
message.Subject = "Test Subject";
message.Body = "This is a test message";
message.IsBodyHtml = true;
// Setup SMTP settings
SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587);
smtp.EnableSsl = true;
NetworkCredential basicCredential = new NetworkCredential("mymail#gmail.com", "******");
smtp.UseDefaultCredentials = false;
smtp.Credentials = basicCredential;
smtp.Send(message);
// save
smtp.EnableSsl = false;
smtp.PickupDirectoryLocation = #"C:\Temp";
smtp.Send(message);
return View();
}
So first i try to send the email. That works. Then i'm trying to save the email to my HDD. But it never gets saved. It does work when i don't send out the email and try to save it to my HDD right away. But i need to do both.
Anyone any idea how i can get this done? I just simply need to log the send messages.
Mail messages in the pickup directory are automatically sent by a local SMTP server (if present), such as IIS. (SmtpClient.PickupDirectoryLocation)
If you want to save to file system, you need to set the DeliveryMethod to SmtpDeliveryMethod.SpecifiedPickupDirectory:
client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
client.PickupDirectoryLocation = #"C:\Temp";
client.Send(message);
See How to save MailMessage object to disk as *.eml or *.msg file
You have to change the property DeliveryMethod to SmtpDeliveryMethod.SpecifiedPickupDirectorynot to not send the email.
Just changing the PickupDirectoryLocation will not work, because the property is not used when DeliveryMethod is set to Network (which is the default value).
See MSDN.

HTML based email not working properly in asp.net web form

I am working on web form which collects certain user information from users and sends confirmation by email. I am trying to user the following approach to send the HTML email as it make managing HTML based email easy.
https://gist.github.com/1668751
I made necessary changes to the code but it is not working. I read other related article to make it work but i am doing something wrong.
Following line of code generates error The replacements dictionary must contain only strings.
MailMessage msgHtml = mailDef.CreateMailMessage(to, replacements, MessageBody, new System.Web.UI.Control());
I have made many change to the code but it doesnt seem to work for me. I would appreciate help to make this code work.
If i comment the above line of code with some other changes then i can send email but i can't replace the token. Any easy approach to replace token is also welcome.
Below is the Complete code i am using right now
String to, subject, Name;
subject = "Booking Confirmation";
Name = txtName.text;
ListDictionary replacements = new ListDictionary();
replacements.Add("<%Name%>", Name);
replacements.Add("<%Email%>", objVR.Email);
replacements.Add("<%CompanyName%>", objVR.CompanyName);
replacements.Add("<%BookingDate%>", objVR.BookingDate);
replacements.Add("<%BookingTime%>", objVR.TimeSlot);
replacements.Add("<%NoOfVisitors%>", objVR.NoOfVisitors);
replacements.Add("<%BookingCode%>", objVR.BookingUniqueID);
MailDefinition mailDef = new MailDefinition();
string MessageBody = String.Empty;
string filePath = System.Web.HttpContext.Current.Request.PhysicalApplicationPath;
using (StreamReader sr = new StreamReader(filePath + #"\en\VREmailEnglish.htm"))
{
MessageBody = sr.ReadToEnd();
}
MailMessage msgHtml = mailDef.CreateMailMessage(to, replacements, MessageBody, new System.Web.UI.Control());
string message = msgHtml.Body.ToString();
Helper.SendTokenEmail(to, subject, msgHtml, isHtml);
public static void SendTokenEmail(string to, string subject, string mailMessage, bool isHtml)
{
try
{
// Create a new message
var mail = new MailMessage();
// Set the to and from addresses.
mail.From = new MailAddress("noreply#somedomain.net");
mail.To.Add(new MailAddress(to));
// Define the message
mail.Subject = subject;
mail.IsBodyHtml = isHtml;
mail.Body = mailMessage.ToString();
//Object userState = mailMessage;
// Create a new Smpt Client using Google's servers
var mailclient = new SmtpClient();
mailclient.Host = "mail.XYZ.net";
//mailclient.Port = 587; //ForGmail
mailclient.Port = 2525;
mailclient.EnableSsl = false;
mailclient.UseDefaultCredentials = true;
// Specify your authentication details
mailclient.Credentials = new System.Net.NetworkCredential("noreply#somedomain.net", "XYZPassword");
mailclient.Send(mail);
mailclient.Dispose();
}
catch (Exception ex)
{
}
}
As pointed out by HatSoft the ListDictionary accepts objects as key and value so this looks like it should work.
But reading the docs for the CreateMailMessage() method here http://msdn.microsoft.com/en-us/library/0002kwb2.aspx indicates you need to convert the value to a string otherwise it will throw an ArgumentException.
So to fix make sure all values you add to the ListDictionary are converted to string i.e
objVR.BookingDate.ToString()

SMTP Mail does not sends for the second call

Here is the code which calls the sendmail method. The problem is that only the first call of sendmail sends the mail to the receiver. The second time when sendmail is called , it gets executed perfectly but never delivers any mail. If I put the application in debug mode and then execute it step by step both the mails get delivered. It seemed like the execution speed of the program is so fast that something goes wrong. Therefore I kept a delay below send function, so it started working fine for me, But I don't think it is a perfect solution. Anybody has any clue what is going on here.
if (!String.IsNullOrEmpty(SendMailAdmin))
{
SendMail(SendMailFrom, SendMailAdmin, Subject, AdminMessageText + "<br>" + MessageText);
}
if (!String.IsNullOrEmpty(SendMailOwner))
{
SendMail(SendMailFrom, SendMailOwner, Subject, OwnerMessageText + "<br>" + MessageText);
}
public void SendMail(String MessageFrom, String MessageTo, String MessageSubject, String MessageBody)
{
MailMessage Message = new MailMessage();
Message.Priority = MailPriority.High;
Message.From = new MailAddress(MessageFrom);
Message.To.Add(MessageTo);
Message.Subject = MessageSubject;
Message.IsBodyHtml = true;
Message.Body = MessageBody;
try
{
SmtpClient client = new SmtpClient(SMTPServer, Convert.ToInt32(SMTPPort));
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("{myusername}", "{mypassword}");
client.Send(Message);
System.Threading.Thread.Sleep(3000);
}
catch
{
throw;
}
}
I personally think the only thing that'll work for you at this point is the delay code .#Shadow is right , this is how servers are configured

Categories