SMTP Mail does not sends for the second call - c#

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

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.

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

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))

How to resolve "The operation has timed out."?

I'm trying to send email using C# code, email was sent when I send it to single person but it is not getting sent when I send it to multiple persons. and getting an error "The operation has timed out." I'm not getting the reason behind it. Please help to find the reason.
Code:
public string SendEmail(List<string> ToEmailAddresses,string body, string emailSubject)
{
var smtp = new SmtpClient { DeliveryMethod = SmtpDeliveryMethod.Network };
smtp.Host = "xyz-host-name";
smtp.Port = 25;
smtp.EnableSsl = false;
var fromAddress = new MailAddress(ConfigurationManager.AppSettings["MailUserName"], "Rewards and Recognition Team");
using (var message = new MailMessage() { Subject = emailSubject, Body = body })
{
message.From = fromAddress;
foreach (string email in ToEmailAddresses)
{
message.To.Add(email);
}
message.IsBodyHtml = true;
try
{
_logger.Log("EmailService-SendEmail-try");
smtp.Send(message);
return "Success";
}
catch (Exception ex)
{
_logger.Log("EmailService-SendEmail-" + ex.Message);
return "Error";
}
}
}
Whenever you're attempting to do anything which may take some time, it's always best practice to run it in a separate thread or use an asynchronous method.My recommendation would be to use the SmtpClient.SendAsync method. To do this, change:
public string SendEmail(List<string> ToEmailAddresses, string body, string emailSubject)
to:
public async string SendEmail(List<string> ToEmailAddresses, string body, string emailSubject)
and include await smtp.SendAsync(...) rather than smtp.Send(...). This will allow further execution of the UI thread whilst sending the mail and not make the application grey out with the "not responding" message.To read more about smtp.SendAsync(...) including parameters and remarks, take a look at the MSDN documentation regarding the method.

Sending email via Google

i have this snippet code to send an email but every time i excute it ,i get this exception
The wait operation period expired
public static void CreateTimeoutTestMessage(string server)
{
string to = "touilhaythem1#gmail.com";
string from = "raddaouirami#gmail.com";
string subject = "Using the new SMTP client.";
string body = #"Using this new feature, you can send an e-mail message from an application very easily.";
MailMessage message = new MailMessage(from, to, subject, body);
SmtpClient client = new SmtpClient(server, 587);
client.EnableSsl = true;
client.Credentials=new NetworkCredential("raddaouirami#gmail.com", "XXXXXXXXX");
Console.WriteLine("Changing time out from {0} to 100.", client.Timeout);
client.Timeout = 100;
// Credentials are necessary if the server requires the client
// to authenticate before it will send e-mail on the client's behalf.
//client.Credentials = CredentialCache.DefaultNetworkCredentials;
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in CreateTimeoutTestMessage(): {0}",
ex.ToString());
}
Console.ReadLine();
}
Of course you get a timeout - you specified 100ms for the timeout. That's pretty short. Contacting the server and sending the mail probably takes more than 100ms. Try something like 10000ms for ten seconds.
I know it's in the MSDN sample you copied and pasted from, but its way too short. It's best to remove the following lines:
Console.WriteLine("Changing time out from {0} to 100.", client.Timeout);
client.Timeout = 100;
Please try this (got the idea from here):
...
MailMessage message = new MailMessage(from, to, subject, body);
SmtpClient client = new SmtpClient(server, 587);
client.EnableSsl = true;
client.UseDefaultCredentials = false; // <--- NEW
client.Credentials = new NetworkCredential("raddaouirami#gmail.com", "XXXXXXXXX");
It might wait for authentication.
Where you have:
SmtpClient client = new SmtpClient(server, 587);
Break it up into:
SmtpClient client = new SmtpClient();
client.Host = "smtp.gmail.com";
client.Port = 587;
Because I don't see where you have defined server, and if you're trying to use gmail you can just declare it as the host like that to see if this gets you one step closer to your goal.
Also a side note, gmail smtp does not allow you to change the send from address, to prevent phishing, so if you did plan on allowing input to change the from variable it won't work, gmail defaults to the email provided in the credentials

Doubts on sending more than one email asynchronously in MVC3

In my application I have a functionality to save and publish articles. So when I click on "Save and Publish" button three things happened:
Published articles get saved in database.
A Notification email goes to a group of users that a new articles is available.
After sending emails page get redirect to "Article Listing" page without showing any success or failure message for an email.
Now Number of users who will receive emails can vary say for e.g 10, 30 50 and so on. I want to send notification emails asynchronously so that page won't get block until all the mails doesn't go to their receptionists.
Given below is a piece of code from "PublishArticle" action method
foreach (string to in emailIds)
{
ArticleNotificationDelegate proc = Email.Send;
IAsyncResult asyncResult = proc.BeginInvoke(subject, body, to, from, cc, null, null, null);
}
Below I have defined a delegate to invoke Send method
private delegate bool ArticleNotificationDelegate (string subject, string body, string to, string from, string cc, string bcc = null);
and this is the code to send an email:
public static bool Send(string subject, string body, string to, string from, string cc, string bcc = null)
{
bool response;
MailMessage mail = new MailMessage();
MailAddress fromAddress = new MailAddress(from);
mail.To.Add(to);
if (!string.IsNullOrWhiteSpace(cc))
{
mail.CC.Add(cc);
}
if (!string.IsNullOrWhiteSpace(bcc))
{
mail.Bcc.Add(bcc);
}
mail.From = fromAddress;
mail.Subject = subject;
mail.Body = body;
mail.IsBodyHtml = true;
mail.Priority = MailPriority.High;
SmtpClient client = new SmtpClient();
try
{
client.Send(mail);
response = true;
}
catch (Exception)
{
response = false;
}
finally
{
client.Dispose();
mail.Dispose();
}
return response;
}
Although this code is working fine but still I want to know that whether my this approach is fine and will not cause any problem in future.
If there is a better approach to accomplish my objective then please suggest me.
Note: As I am using .net framework 4.0 so cannot use the new features of Asyn and await available in 4.5.
Also I had used method client.SendAsync by simply replacing the client.Send and rest of my code in above Send method was same. After this change NO mails were being send and also it did not throw any exception. So I did not go with this change.
I want to send notification emails asynchronously so that page won't get block until all the mails doesn't go to their receptionists.
That's a very dangerous approach, because ASP.NET will feel free to tear down your app domain if there are no active requests. ASP.NET doesn't know that you've queued work to its thread pool (via BeginInvoke). I recommend that you use a solution like HangFire to reliably send email.

Categories