1

I'm using the System.Net.Mail. There are some topics around this area, but they are ASP.NET and often VB related. I'm isolating the code into a desktop skeleton code, I use .NET 3.5 and C#. So Send works in all scenario what I tried (EnableSsl false/true, UseDefaultCredentials false/true). But SendAsync only works if UseDefaultCredentials is not set to true (turns out that it can even matter if you explicitly set it to false, it's false by default), EnableSsl is true (OK, that can be server settings too), and hard-code my credentials. I want to be able to SendAsync using UseDefaultCredentials. Code:

void sendmail() {
  MailMessage email = new MailMessage();
  email.From = new MailAddress("tcs@software.com");
  email.To.Add("tcs@software.com");
  email.Subject = "Simple test email subject";
  email.Body = "Simple test email body";
  string mHost = "mail.software.com";
  string mUsername = @"DOMAIN\tcs";
  string mPassword = "myfreakinpassword?Really???";
  SmtpClient smtpCli = new SmtpClient(mHost);
  //smtpCli.UseDefaultCredentials = true;
  smtpCli.Credentials = new NetworkCredential(mUsername, mPassword);
  smtpCli.EnableSsl = true;
  smtpCli.SendCompleted += smtpCli_SendCompleted;
  try {
    //smtpCli.Send(email);
    smtpCli.SendAsync(email, null); // This mofo only works in this combination
  }
  catch (Exception ex) {
    Console.WriteLine(ex);
  }
}
void smtpCli_SendCompleted(object sender, AsyncCompletedEventArgs e) {
  if (e.Error != null)
    Console.WriteLine(e.Error);
}
Csaba Toth
  • 10,021
  • 5
  • 75
  • 121
  • What are the exception? – Xharze Feb 26 '13 at 23:35
  • The Exception (in all combinations): "System.Net.Mail.SmtpException: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated at System.Net.Mail.SendMailAsyncResult.End(IAsyncResult result) at System.Net.Mail.SmtpClient.SendMailCallback(IAsyncResult result)". This is also the exception what you get if you simply mistype password or something. But as I said, all (meaningful) scenarios work with Send() and don't work with SendAsync(). – Csaba Toth Feb 26 '13 at 23:40
  • My application is started with my user's privileges. Can it happen that the background thread which executes the mail send task runs with other privileges? This is a desktop software. Even the UseDefaultCredentials=true doesn't work. In the end I may wrap the whole synchronous send into an async layer crafted by me, or wire it into messaging. But then I'll scream into my pillow, SendAsync doesn't make too much sense. I spent how many hours on this now, and it should just work. – Csaba Toth Feb 26 '13 at 23:44
  • So I converted the solution to use Prism's EventAggregator messaging pattern. This way I can achieve Async behavior, if I specify ThreadOption.BackgroundThread. What I can imagine is that in case of SendAsync when I set the UseDefaultCredentials to true it happens in the UI/publisher thread, and later the SendAsync executes in a background worker with slightly different privileges. On the other hand with the messaging solution I'll execute the whole shebang in the background worker thread, so credentials will match under the hood? UseDefaultCredentials works this way. – Csaba Toth Feb 28 '13 at 18:25

1 Answers1

1

Use messaging pattern like Prism's EventAggregator (specifying ThreadOption.BackgroundThread). This way the caller sends a message (the message would contain From, To, Subject, Body), and it is asynchronous from the sender's point of view. Then use the synchronous Send function of System.Net.Mail in the consumer/handler of the message. This probably works because the executing background thread has more proper privileges than the one spawns the SendAsync.

Csaba Toth
  • 10,021
  • 5
  • 75
  • 121