Bir önceki yazımızda onay mailinde kullanacak olduğumuz linki oluşturmuştuk. Bu yazıda kullanıcı kayıt işlemini gerçekleştirdikten sonra oluşturulacak olan linki kullanıcının mail adresine gönderme işlemini gerçekleştireceğiz. Bunun için aşağıdaki komutu Package Manager üzerinde çalıştırıyoruz.
Install-Package MailKit
Projenin appsettings.json dosyasını aşağıdaki şekilde düzenliyoruz.
{
"ConnectionStrings": {
"ApplicationDbContextString": "Server=.;Database=IdentityCustomProjectDB;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"EmailConfig": {
"UserName": "<Email Kullanıcı Adı>",
"Password": "<Şifre>",
"Host": "<Mail Hostu>",
"Port": <Port Bilgisi>
}
}
Yukarıda görüldüğü gibi EmailConfig adında bir section oluşturduk ve onay linkini gönderecek olan mail adresimizin bilgilerini burada tanımladık. Şimdi projemize DTOs adında bir klasör ekleyip içinde EmailConfigDto.cs adında bir sınıf oluşturuyoruz. Bu sınıfı oluşturmamamızın sebebi ilerleyen aşamalarda appsettings.json da belirlediğimiz konfigürasyon verilerini istediğimiz sınıfa taşıyabilmek olacak. EmailConfigDto.cs sınıfını aşağıdaki şekilde düzenliyoruz.
namespace IdentityCustomProject.DTOs
{
public class EmailConfigDto
{
public string UserName { get; set; }
public string Password { get; set; }
public string Host { get; set; }
public int Port { get; set; }
}
}
Models klasöründe EmailoModel.cs dosyası oluşturup aşağıdaki şekilde düzenliyoruz.
namespace IdentityCustomProject.DTOs
{
public class EmailDto
{
public string To { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
}
Şimdi dinamik yani ilgili kullanıcı adını ve ilgili onay linkini içerecek olan bir html dosyası oluşturacağız, bunun için wwwroot klasörünün altına Templates ve bu klasörün de altına EmailTemplates adında bir klasör oluşturuyoruz bu klasörün de altına ConfirmEmail.html dosyası oluşturup aşağıdaki şekilde düzenliyoruz.
<!DOCTYPE html>
<html>
<body>
<h5 class="card-title">Welcome</h5>
<p class="card-text">Hi, {0}</p>
<p class="card-text">Thank you for your registration. Before try to login, you need to confirm your account. Just click the link below.</p>
<a class="btn btn-primary" href="{1}" role="button">Confirm Account</a>
</body>
</html>
Görüldüğü gibi basit bir HTML dosyası oluşturduk HTML düzenlenmek istenirse bir css dosyası oluşturulup düzenlenebilir. AccountController.cs dosyasını düzenlerken bu dosyayı dinamik olarak düzenlemek için dosyayı string olarak okuyup ilgili alanları formatlayarak dinamik hale getireceğiz.
Şimdi Email gönderimi için bir service oluşturacağız bunun için projenin ana dizininde, Services ve onun altına EmailService adında iki klasör, ardından da IEmailService.cs adında bir interface oluşturuyor ve aşağıdaki şekilde düzenliyoruz.
using IdentityCustomProject.Models;
namespace IdentityCustomProject.Services.EmailService
{
public interface IEmailService
{
void SendEmail(EmailDto email);
}
}
Ve ardından bu interface’i kullanacağımız EmailService.cs dosyasını da oluşturup aşağıdaki şekilde düzenliyoruz.
using IdentityCustomProject.DTOs;
using IdentityCustomProject.Models;
using MailKit.Net.Smtp;
using MimeKit;
using MimeKit.Text;
namespace IdentityCustomProject.Services.EmailService
{
public class EmailService : IEmailService
{
private readonly IConfiguration _configuration;
public EmailService(IConfiguration configuration)
{
_configuration = configuration;
}
public void SendEmail(EmailDto email)
{
var section = _configuration.GetSection("EmailConfig").Get<EmailConfigDto>();
var emailKit = new MimeMessage();
emailKit.From.Add(MailboxAddress.Parse(section.UserName));
emailKit.To.Add(MailboxAddress.Parse(email.To));
emailKit.Subject = email.Subject;
emailKit.Body = new TextPart(TextFormat.Html) { Text = email.Body };
using var smtpKit = new SmtpClient();
smtpKit.Connect(section.Host, section.Port, true);
smtpKit.Authenticate(section.UserName, section.Password);
smtpKit.Send(emailKit);
smtpKit.Disconnect(true);
smtpKit.Dispose();
}
}
}
Yukarda 20. satırda görüldüğü gibi DTO klasörü altındaki EmailConfigDto sınıfı aracılığıyla appsettings.json da tanımladığımız gönderici mail bilgilerini EmailService kullanabilir hale geldik.
Sırada oluşturduğumuz service’i kullanmak üzere gerekli olan scoped’ı açmak için aşağıdaki kodu Program.cs dosyasına ekliyoruz.
builder.Services.AddScoped<IEmailService, EmailService>();
Ve geriye son olarak kontroller sınıfında yapacağımız değişiklikler kalıyor. İlk olarak asağıdaki iki property’i sınıfa ekliyor ve AccountController sınıfının kurucu metodunu aşağıdaki şekilde düzenliyoruz.
private readonly IEmailService _emailService;
private readonly IWebHostEnvironment _webHostEnvironment;
public AccountController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager, IEmailService emailService, IWebHostEnvironment webHostEnvironment)
{
_userManager = userManager;
_signInManager = signInManager;
_emailService = emailService;
_webHostEnvironment = webHostEnvironment;
}
Ardından Register metodumuzun içinde yer alan if (result.Succeeded) koşulumuzu aşağıdaki şekilde düzenliyoruz.
if (result.Succeeded)
{
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var emailConfirmationLink = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, token = token }, Request.Scheme);
ViewBag.SuccessMessage = "Registration succesful. Before try to login, please confirm your email" +
" by clicking on the confirmation link we have emailed you.";
var templatePath = _webHostEnvironment.WebRootPath
+ Path.DirectorySeparatorChar.ToString()
+ "Templates" + Path.DirectorySeparatorChar.ToString()
+ "EmailTemplates" + Path.DirectorySeparatorChar.ToString()
+ "ConfirmEmail.html";
string htmlBody = "";
using (StreamReader streamReader = System.IO.File.OpenText(templatePath))
{
htmlBody = streamReader.ReadToEnd();
}
string emailBody = string.Format(htmlBody, user.Name, emailConfirmationLink);
EmailDto email = new EmailDto
{
To = "erkutakyaz@gmail.com",
Subject = "Email Confirmation",
Body = emailBody
};
_emailService.SendEmail(email);
return View();
}