Hi @Hamza Abbasi ,
From your description of the question, I think you have scaffolded identity code and you don't want to create a controller to send email.
You can create a service to send email and inject this service into Register.cshtml.cs
.
First, You need to scaffolded Account.RegisterConfirmation
.
Here I'm using Mailkit to send email, You can also use another email provider.
Installing NuGet package MailKit
Create a service to send email:
public class SendEmail
{
public void send(string UserName,string body)
{
var email = new MimeMessage();
email.From.Add(MailboxAddress.Parse("EmailName"));
email.To.Add(MailboxAddress.Parse(UserName));
email.Subject = "Confirm your account";
email.Body = new TextPart(MimeKit.Text.TextFormat.Html) {Text = body };
using var smtp = new SmtpClient();
//Here i'm using smtp.ethereal to test, you can also use another SMTP server provides.
smtp.Connect("smtp.ethereal.email", 587, MailKit.Security.SecureSocketOptions.StartTls);
smtp.Authenticate("EmailName", "Password");
smtp.Send(email);
smtp.Disconnect(true);
}
}
Then register this server in your startup.cs
services.AddScoped<SendEmail>();
You need to inject SendEmail into your Register.cshtml.cs
and change some code:
public class RegisterModel : PageModel
{
//.........
private readonly SendEmail _sendEmail;
public RegisterModel(SendEmail sendEmail)
{
_sendEmail = sendEmail;
}
//........
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
//.........
if (result.Succeeded)
{
//.................
//.........add this code here......
_sendEmail.send(Input.Email, $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
//.........
}
Finally, You need to change to DisplayConfirmAccountLink = false
in RegisterConfirmation.cshtml.cs.
Now, When user register account, It will send email to user.
You can also refer to these articles to learn more: Article1, Article2.
=================Update=====================
You don't need to remove any code in Register.cshtml.cs
. In My answer, I write a class(SendEmail) as a service to send email right? I have used:
services.AddScoped<SendEmail>();
to register this service in startup.cs
, Now we need to inject this service into Register.cshtml.cs
(If you are not familiar with dependency injection in Asp.Net Core, you can refer to this link)
public class RegisterModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly IUserStore<IdentityUser> _userStore;
private readonly IUserEmailStore<IdentityUser> _emailStore;
private readonly ILogger<RegisterModel> _logger;
//inject service into this class
private readonly SendEmail _sendEmail;
public RegisterModel(
UserManager<IdentityUser> userManager,
IUserStore<IdentityUser> userStore,
SignInManager<IdentityUser> signInManager,
ILogger<RegisterModel> logger,
SendEmail sendEmail)
{
_userManager = userManager;
_userStore = userStore;
_emailStore = GetEmailStore();
_signInManager = signInManager;
_logger = logger;
_sendEmail = sendEmail;
}
//.............other code........
//in OnPostAsync method, we need to use send method in SendEmail service
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
//.........
if (result.Succeeded)
{
//.................
//use send method in SendEmail service.
_sendEmail.send(Input.Email, $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
//.............
}
In the above code, I injected the SendEmail service into Register.cshtml.cs and called the send method in the SendEmail service in the OnPostAsync method.
---------------------------------------------------------------------------------------------------------------------------------------------------------
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Xinran Shen