2014-04-01 13 views
27

Ho implementato un semplice EmailService per Asp.Net Identity 2.0 (tramite l'interfaccia IIdentityMessageServiceAsp.Net Identity 2.0 - Come implementare IIdentityMessageService per fare SMTP asincrono usando SmtpClient? .

public class EmailService : IIdentityMessageService 
{ 
    public Task SendAsync(IdentityMessage message) 
    { 
     // convert IdentityMessage to a MailMessage 
     var email = 
      new MailMessage(new MailAddress("[email protected]", "(do not reply)"), 
      new MailAddress(message.Destination)) 
     { 
      Subject = message.Subject, 
      Body = message.Body, 
      IsBodyHtml = true 
     }; 

     using (var client = new SmtpClient()) // SmtpClient configuration comes from config file 
     { 
      return client.SendMailAsync(email); 
     } 
    } 
} 

Per inviare una e-mail, vado attraverso UserManager:

await _userManager.SendEmailAsync(user.Id, "Confirm your account","Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>");

Il problema è che ho un System.Threading.Tasks.TaskCanceledException quando chiamo SendEmailAsync() e non è chiaro il perché.

Se invio e-mail in modo sincrono (client.Send(email)), Eve tutto funziona bene.

Quindi le mie domande sono:

  • Come posso evitare il TaskCanceledException da farsi espellere? e (supponendo posso superare questo errore),

  • Come devo fare per comunicare gli errori durante l'invio di email al client (cioè, risposte di tipo "utente inesistente" dal SmtpClient?

+0

Qui è la vostra risposta dettagli https://stackoverflow.com/a/45789677/3835843 – Arif

risposta

30

tuo problema è che SmtpClient è disposto prima che il messaggio viene inviato

due modi:.

  • attendono il risultato SendMailAsync

    using (var client = new SmtpClient()) 
    { 
        await client.SendMailAsync(email); 
    } 
    
  • registrare l'evento SendCompleted e smaltire l'SmtpClient solo dopo che il messaggio viene inviato

    var client = new SmtpClient(); 
    client.SendCompleted += (s, e) => { 
        client.Dispose(); 
    }; 
    return client.SendMailAsync(message); 
    
+0

Non posso aspettare il SendMailAsync() (almeno non con alcuni altri ginnastica) perché l'IIdentityMessageService.SendAsync () metodo ha un tipo di ritorno di attività. Ma il secondo suggerimento sembra che funzionerà. Grazie. –

+7

È possibile attendere il metodo 'SendMailAsync'. Aggiungi 'async' /' await' e non restituire nulla. Il compilatore farà il suo lavoro. – meziantou

+4

Ho affrontato questo stesso problema e ho scritto una descrizione completa qui: http://blog.falafel.com/avoid-taskcanceledexception-sending-email-async/ – ssmith

5

si deve mettere asincrona sul metodo.

public async Task SendAsync(IdentityMessage message) 
    { 
     using (SmtpClient client = new SmtpClient()) 
     { 
       using (var mailMessage = new MailMessage("[email protected]", message.Destination, message.Subject, message.Body)) 
       { 
        await client.SendMailAsync(mailMessage); 
       } 
      } 
     } 
    } 
Problemi correlati