0

I am using SmtpClient in ASP.NET C# for sending emails asynchronously. I need the original MailMessage in SendCompleted callback in order to log the subject to a database. But e.UserState is null.

public class SendMessage
{
    public async Task Send()
    {
        // rest of the code
        SmtpClient client = new SmtpClient(host, port);
        client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
        await client.SendMailAsync(message);
    }

    private async void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
        SmtpClient callbackClient = sender as SmtpClient;
        MailMessage callbackMailMessage = e.UserState as MailMessage; // always null

        // mailMessage subject is needed for logging purposes
        LogClass NewLog = new LogClass();
        await NewLog.AddAsync(LogTypes.SendMail, LogSubTypes.Other, $" email sent with subject: {callbackMailMessage.Subject }");


        callbackClient.Dispose();
        callbackMailMessage.Dispose(); //will throw a NullReferenceException
    }
}

What am I doing wrong?

H. Asgari
  • 1
  • 1
  • 3
  • Do you know what the as operator does? If you research that, you'll understand why it's always null. – mason Mar 07 '18 at 05:15
  • You don't need that event. Just do what you need with message right after `await client.SendMailAsync(message);`. – Evk Mar 07 '18 at 06:19
  • @mason Yes, I do. The `as` operator is similar to cast operation and it returns null because it can't do the conversion. My question is that why I am getting the `callbackClient` but not the `callbackMailMessage` – H. Asgari Mar 07 '18 at 16:46
  • @Evk I need to log to a database and also dispose my objects to free up resources upon completion of the task. How do I know if it's done after `client.SendMailAsync(message);` ? – H. Asgari Mar 07 '18 at 17:02
  • Because you are using `await`. If you know what await is - you should know that it's done after it (or exception is thrown if something went wrong, which you can catch with regular try-catch). – Evk Mar 07 '18 at 17:03
  • 1
    So in conclusion, this callback isn't even needed. And the reason `callbackMailMessage` is always null is that `e.UserState` isn't a MailMessage. – mason Mar 07 '18 at 17:39
  • Thanks everyone, I understand that I don't need a callback in my case. Also I learned that If I wanted the email subject in the callback, I should have used `SendAsync(MailMessage message, object userToken);` instead. – H. Asgari Mar 07 '18 at 19:16

0 Answers0