Click here to Skip to main content
15,887,326 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
I'm learning ASP .NET and I'd want to make a simple registration/login page. I've created my public class AccountController : Controller, then I created Startup class and I've written the Configure method and finally I implemented EmailSender class. When I register a new user I can see it into the database but I don't receive any mail and I can't log in with the new user if I try.

I've watched some tutorials on YouTube, read posts here on CodeProject about it and read the Microsoft documentation. To me it seems correct compared with what I've done, but surely I have to modify something and I don't notice it. Any help?

What I have tried:

public class AccountController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly IEmailSender _emailSender;
    private readonly ILogger _logger;

    public AccountController(
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        IEmailSender emailSender,
        ILogger<AccountController> logger)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _emailSender = emailSender;
        _logger = logger;
    }
    
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, set lockoutOnFailure: true
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation("Utente loggato.");
                return RedirectToLocal(returnUrl);
            }
            if (result.RequiresTwoFactor)
            {
                return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
            }
            if (result.IsLockedOut)
            {
                _logger.LogWarning("User bloccato.");
                return RedirectToAction(nameof(Lockout));
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Tentativo di login fallito.");
                return View(model);
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }
    
    public IActionResult Register(string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]

    public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await _userManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                _logger.LogInformation("L'utente ha creato un nuovo account con una nuova password.");

                var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
                await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);

                //diallowed signin for self registration, email should be confirmed first
                //await _signInManager.SignInAsync(user, isPersistent: false);
                _logger.LogInformation("L'utente ha creato un nuovo account con una nuova password.");
                return RedirectToConfirmEmailNotification();
            }
            AddErrors(result);
        }
        return View(model);
    }
    
    public async Task<IActionResult> ConfirmEmail(string userId, string code)
    {
        if (userId == null || code == null)
        {
            return RedirectToAction(nameof(HomeController.Index), "Home");
        }
        var user = await _userManager.FindByIdAsync(userId);
        if (user == null)
        {
            throw new ApplicationException($"Unable to load user with ID '{userId}'.");
        }
        var result = await _userManager.ConfirmEmailAsync(user, code);
        return View(result.Succeeded ? "ConfirmEmail" : "Error");
    }
}



Startup class:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Landing}/{action=Index}/{id?}");
    });
}


EmailSender:

public async Task SendEmailAsync(string email, string subject, string message)
{
    await _netcoreService.SendEmailBySendGridAsync(_sendGridOptions.SendGridKey,
        _sendGridOptions.FromEmail,
        _sendGridOptions.FromFullName,
        subject,
        message,
        email);
}
Posted
Comments
BabyYoda 2-Dec-20 14:22pm    
Does the email get sent?

You either have to write the code to do what you want or use the built in identity stuff that asp.net has. It's not clear which route you are going.
GodEner 3-Dec-20 3:17am    
I forgot to insert the code on the What I've Tried Section. This is what I did into AccountController class:

public async Task<iactionresult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
_logger.LogInformation("L'utente ha creato un nuovo account con una nuova password.");

var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);

//diallowed signin for self registration, email should be confirmed first
//await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("L'utente ha creato un nuovo account con una nuova password.");
return RedirectToConfirmEmailNotification();
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}

NetcoreService class:

public async Task SendEmailBySendGridAsync(string apiKey, string fromEmail, string fromFullName, string subject, string message, string email)
{
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage()
{
From = new EmailAddress(fromEmail, fromFullName),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
msg.AddTo(new EmailAddress(email, email));
await client.SendEmailAsync(msg);

}

When I create a new user I pass to this part of code correctly, but as I've already said I can't find the mail in my inbox, neither in the spam.
BabyYoda 3-Dec-20 7:24am    
Debug the code to make sure the call to send email is actually getting called. And then debug the email code to make sure it's actually getting sent.

Basically, you just need to do some debugging first.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900