Search code examples
c#asp.netasp.net-mvcasp.net-coreasp.net-identity

ASP.NET MVC to ASP.NET CORE 2.2 migration: How to send messages (SMS, email, etc.)


MVC Assembly: Microsoft.AspNet.Identity.UserManager

CORE Assembly: Microsoft.Extensions.Identity.Core

I am migrating from MVC to .NET CORE 2.2. I have created a MyManager class that inherits from UserManager. The UserManager class in MVC has the following properties:

public IIdentityMessageService EmailService { get; set; }

public IIdentityMessageService SmsService { get; set; }

In .NET CORE 2.2., the UserManager does not have these properties. I am guessing that the MVC UserManager uses those properties to automatically send messages. It looks like it uses the EmailService to automatically send the message that verifies the email address. However, this behavior does not appear to happen in .NET CORE. So, it looks like the UserManager no longer handles this.

The question is this: How do you verify a user's email address?

Is this being handled in a different Microsoft assembly or has Microsoft gotten out of that business and farmed it off to a 3rd-party assembly? Or, is there something else?


Solution

  • this is how i send email verification using Sendgrid in asp.net core.

    step 1 : Create a class called EmailSender that implements IEmailSender Interface(need to include using Microsoft.AspNetCore.Identity.UI.Services; for IEmailSender) :

     public class EmailSender : IEmailSender
    {
        public async Task SendEmailAsync(string email, string subject, string htmlMessage)
        {
            var apiKey = "send grid api key";
            //it looks like this  :
            // var apiKey = "SG.2MpCzyTvIQ.WhHMg6-VBjuqbn9k-8P9m6X9cHM73fk2fzAT5sA4zKc"; 
    
            var client = new SendGridClient(apiKey);
            var from = new EmailAddress($"[email protected]", "Email title");
            var to = new EmailAddress(email, email);
            var plainTextContent = htmlMessage;
            var htmlContent = htmlMessage;
            var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
            try
            {
                var response = await client.SendEmailAsync(msg);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            //return Task.CompletedTask;
        }
    }
    

    Step 2 : You need to add it as a service using Dependency Injection inside the Startup.cs file

     services.AddTransient<IEmailSender, EmailSender>();
    

    Step 3 : Inject it into the constructor of the class you want to use it in.

       [AllowAnonymous]
    public class RegisterModel : PageModel
    {
          private readonly IEmailSender _emailSender;
    
        public RegisterModel(IEmailSender emailSender)
        {
            _emailSender = emailSender;
        }
    
         public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser
                               {
                                    UserName = Input.Email,
                                    Email = Input.Email,
                                    DateCreated = DateTime.Now
                                };
                var result = await _userManager.CreateAsync(user, Input.Password);
                if (result.Succeeded)
                {
                    _logger.LogInformation("User created a new account with password.");
                    returnUrl = Url.Action("ConfirmEmail", "Home");
                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    await _userManager.AddToRoleAsync(user,"ROleName");
                    var callbackUrl = Url.Page(
                        "/Account/ConfirmEmail",
                        pageHandler: null,
                        values: new { userId = user.Id, code = code },
                        protocol: Request.Scheme);
    
                   await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                        $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
    
                    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();
        }
    

    and this should send your email. it works for me and it should for you too.