0

I'm trying to send an email with SmtpClient.SendMailAsync and it doesn't work although the synchronous version works (SmtpClient.Send).

My synchronous code :

            MailMessage msg = new MailMessage();
            msg.To.Add(new MailAddress("someEmail@gmail.com", "SomeOne"));
            msg.From = new MailAddress("no-reply@group.com", "You2");
            msg.Subject = "This is a Test Mail";
            msg.Body = "This is a test message";
            msg.IsBodyHtml = true;

            SmtpClient client = new SmtpClient();
            client.UseDefaultCredentials = true;
            client.Port = 25; 
            client.Host = "mail.group.com";
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.EnableSsl = true;
            client.Send(msg);

My asynchronous email code (I just modified the EmailService : IIdentityMessageService class) :

public Task SendAsync(IdentityMessage message)
{

    const string sentFrom = "support@group.com";

    // Configure the client:
    var client = new SmtpClient("mail.group.com")
    {
        Port = 25,
        DeliveryMethod = SmtpDeliveryMethod.Network,
        UseDefaultCredentials = true,
        EnableSsl = true
    };

    // Create the message:
    var mail = new MailMessage(sentFrom, message.Destination, message.Subject, message.Body);

    // Send:
    return client.SendMailAsync(mail);
}

Edit : the calling code is generated by Visual Studio, here it is :

public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);

                    // Send an email with this link
                     string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                     var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                     await UserManager.SendEmailAsync(user.Id, "Confirmer votre compte", "S'il vous plaît, cliquez le lien suivant :  <a href=\"" + callbackUrl + "\">Activation</a>");

                    return RedirectToAction("Index", "Home");
                }
                AddErrors(result);
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
MusicAndCode
  • 870
  • 8
  • 22
  • Why not make a fire and forget ? just change the method to `async void` and call await in `client.SendMailAsync(mail)` – Lucas Jan 16 '17 at 18:29
  • Because it's already like this in the code generated by MVC. Nice name :-) – MusicAndCode Jan 16 '17 at 18:32
  • It is most probably a combination of http://stackoverflow.com/questions/22797845/asp-net-identity-2-0-how-to-implement-iidentitymessageservice-to-do-async-smtp and http://stackoverflow.com/questions/15021304/an-async-await-example-that-causes-a-deadlock – Eugene Podskal Jan 16 '17 at 18:38
  • @MusicAndCode Thanks : ) – Lucas Jan 16 '17 at 19:36

2 Answers2

0

At the moment you are returning the Task instead of void, you will need to make sure in your calling code you await the returned Task, or use .Wait().

In this case, there is no need to make your SendAsync method async and await the SendMailAsync call, but if you are in doubt, then you typically should just to avoid some nasty edge cases.

Stuart
  • 5,358
  • 19
  • 28
0

Just talked to my server guy. The problem was that support@group.com is blocked by the email server but not no-reply@group.com.

MusicAndCode
  • 870
  • 8
  • 22