Search code examples
c#emailasync-awaitmailkit

How to Display MailKit Response from an Inline Async Event Handler in C#


I am implementing MailKit in C# to send an email.

I need to be able to see the response from the server.

The MessageSent event handler is hooked up as an inline async method.

I am sure this is why the response from the SmtpClient is always empty. However I don't understand how to extract the response message correctly.

           var messageToSend = new MimeMessage
            {
                Subject = subject,
                Body = new TextPart(MimeKit.Text.TextFormat.Text) {Text = message_body } 
            };

            foreach (var recipient in recipients)
                messageToSend.To.Add(new MailboxAddress(recipient.Name, recipient.Address));

            var message = "";
            using (var smtp = new MailKit.Net.Smtp.SmtpClient())
            {
                smtp.MessageSent += async (sender, args) =>
                {  // args.Response };
                    smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;

                    await smtp.ConnectAsync(Properties.Settings.Default.Email_Host, 587, SecureSocketOptions.StartTls);
                    await smtp.AuthenticateAsync(Properties.Settings.Default.Test_Email_UserName, 
                                                 Properties.Settings.Default.Test_Email_Password);
                    await smtp.SendAsync(messageToSend);
                    await smtp.DisconnectAsync(true);
                   
                    MessageBox.Show(args.Response);// <== doesn't display
                    message =args.Response;// <== this is my second attempt at getting at the response
                };
                 
            }
            MessageBox.Show(message);// <== always display empty string

Solution

  • What you need to do is this:

    var message = "";
    using (var smtp = new MailKit.Net.Smtp.SmtpClient())
    {
        smtp.MessageSent += async (sender, args) =>
        {
            message = args.Response
        };
    
        smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
    
        await smtp.ConnectAsync(Properties.Settings.Default.Email_Host, 587, SecureSocketOptions.StartTls);
        await smtp.AuthenticateAsync(Properties.Settings.Default.Test_Email_UserName, 
                                     Properties.Settings.Default.Test_Email_Password);
        await smtp.SendAsync(messageToSend);
        await smtp.DisconnectAsync(true);
    }
    MessageBox.Show(message);
    

    The problem is that your Connect/Authenticate/Send logic was all inside of the event callback, thereby leaving nothing to cause the event to be emitted.