2017-11-24 15 views
0

기본 ASP.NET MVC, ID 템플릿을 사용 중입니다 ... 고객에게 확인 이메일을 보내려고합니다.다른 버전의 SendEmailAsync 가지고 있음

새 프로젝트 템플릿으로 제공되는 디폴트의 구현은, AccountController.cs의 등록 방법을 가지고

public async Task<ActionResult> Register(RegisterViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = new ApplicationUser { UserName = model.Email.Trim(), Email = model.Email.Trim(), FirstName = model.FirstName.Trim(), LastName = model.LastName.Trim() }; 
      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); 
       string message = "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>"; 
       await UserManager.SendEmailAsync(user.Id, "Confirm your account", HttpUtility.UrlEncode(message)); 

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

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

UserManager.SendEmailAsync에 대한 호출이 있습니다, 지금이 방법은 Microsoft.AspNet.Identity에 정의되어 있습니다 나는 그것을 바꾸고 싶지 않다.

실제 이메일 보내기 기능은 그래서는 message.body 이메일을 싶지 않아 ... 이제 당신이보고, 나는 이메일을 보내 Sendgrid을 사용하고 IdentityConfig.cs

public class SendGridEmailService : IIdentityMessageService 
{ 
    public async Task SendAsync(IdentityMessage message) 
    { 
     var apiKey = ConfigurationManager.AppSettings["SendGridApiKey"]; 
     var client = new SendGridClient(apiKey); 
     var msg = new SendGridMessage() 
     { 
      From = new EmailAddress("[email protected]", "DX Team"), 
      Subject = message.Subject, 
      PlainTextContent = message.Body, 
      HtmlContent = message.Body 
     }; 

     msg.TemplateId = /* I want to pass templateId here */ 
     msg.Personalizations[0].Substitutions.Add("confirmurl", /* I want to pass Username here */); 
     msg.Personalizations[0].Substitutions.Add("confirmurl", /* I want to pass confirm url here */); 

     msg.AddTo(new EmailAddress("[email protected]", "Test User")); 
     var response = await client.SendEmailAsync(msg); 

    } 
} 

에 .. 나는 몇몇 템플리트를 만들었고, 나는 템플레이트 ID를 템플리트에서 대체 될 사용자 이름 같은 일부 대체 태그와 함께 전달하려고합니다.

그래서 나는이 일반적인가 SendAsync 방법을 싶지 않아 ... 나는

SendGridAsync(SendGridMessage message) 

같은이 가능한이 방법을 추가하는 것입니다하려는, 그래서 때 SendGridAsync를 호출하는가 SendAsync과를 호출 할 때 선택할 수 있습니까?

+0

서비스. 그런 다음이를 호출 한 다음 그 결과를 UserManager.SendEmailAsync (...)에 전달합니다. 그런 다음 서비스에는 보낼 전자 메일의 각 유형에 대한 구현 세부 정보가 들어 있습니다. –

+0

브렌든에게 감사 드려요. 어떻게해야합니까? SendAsync는 목적지, 제목 및 본문이있는 IdentityMessage 만 허용합니다 ... 내가하고있는 일은 SendGridMessage를 작성하고 SendGridAsync (SendGridMessage 메시지)와 같은 것이 필요하지만 이걸 추가하는 방법을 모르겠습니다 ... – Sarhang

+1

예 문제는 sengrid 템플릿에 있습니다. 문제는 ** 당신이 ** UserManager.SendEmailAsync (...)를 사용하여 이메일을 보내지 않아도된다는 것입니다. 자신의 서비스에서 전자 메일을 보낼 수 있습니다. 구현시 'IIdentityMessageService'를 구현할 필요가 없습니다. 또한 - 당신은'UserManager.SendEmailAsync()'에 대한 호출을 변경하고 싶지 않다고 말합니다 - 왜 그렇지 않습니까? –

답변

1

특히 좀 더 복잡한 작업을 수행하고자 할 때 내장 메일 서비스를 사용할 필요가 없습니다.

자신의 메시징 서비스를 정의하여 DI 프레임 워크

public interface IMyMessageService 
{ 
    Task SendConfirmationMessage(string confirmUrl, string to) 
    // define methods for other message types that you want to send 
} 

public class MyMessageServie : IMyMessageService 
{ 
    public async Task SendConfirmationMessage(string confirmUrl, string to) 
    { 
     var apiKey = ConfigurationManager.AppSettings["SendGridApiKey"]; 
     var client = new SendGridClient(apiKey); 
     var msg = new SendGridMessage() 
     { 
      From = new EmailAddress("[email protected]", "DX Team"), 
      Subject = message.Subject, 
      PlainTextContent = message.Body, 
      HtmlContent = message.Body 
     }; 

     msg.TemplateId = /* I want to pass templateId here */ 
     msg.Personalizations[0].Substitutions.Add("confirmurl", confirmUrl); 

     msg.AddTo(new EmailAddress(to, "Test User")); 
     var response = await client.SendEmailAsync(msg); 

    } 
} 

등록 IMyMessageService하고, 이메일은 (예를 들어,이 AccountController)로부터 전송되는 컨트롤러에 주입.

지금과 같을 것이다 당신의 레지스터 조치는 (내가 IMyMessageService을 주입 _myMessageService의 인스턴스가 한 가정) :

public async Task<ActionResult> Register(RegisterViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     var user = new ApplicationUser { UserName = model.Email.Trim(), Email = model.Email.Trim(), FirstName = model.FirstName.Trim(), LastName = model.LastName.Trim() }; 
     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); 

      // USE YOUR MESSAGE SERVICE 
      await _myMessageService.SendConfirmationMessage(callbackUrl, user.Email); 

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

    // If we got this far, something failed, redisplay form 
    return View(model); 
} 
내가 별도로 이메일 * 내용 *의 건물을 리팩토링 볼 것