0

我正在学习 ASP .NET,我想做一个简单的注册/登录页面。

public class AccountController : Controller以这种方式创建了我的:

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 类,并编写了以下方法:

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?}");
    });
}

当我注册一个新用户时,我可以在数据库中看到它,但我没有收到任何邮件,如果我尝试,我无法使用新用户登录。

我在 YouTube 上观看了一些关于它的教程并阅读了 Microsoft 文档。对我来说,与我所做的相比,这似乎是正确的,但我肯定必须修改一些东西而我没有注意到它。

编辑:这是我为 EmailSender 和 NetcoreService 类所做的:

public class EmailSender : IEmailSender
{        
    private SendGridOptions _sendGridOptions { get; }
    private INetcoreService _netcoreService { get; }
    private SmtpOptions _smtpOptions { get; }

    public EmailSender(IOptions<SendGridOptions> sendGridOptions,
        INetcoreService netcoreService,
        IOptions<SmtpOptions> smtpOptions)
    {
        _sendGridOptions = sendGridOptions.Value;
        _netcoreService = netcoreService;
        _smtpOptions = smtpOptions.Value;
    }


    public Task SendEmailAsync(string email, string subject, string message)
    {
        //send email using sendgrid via netcoreService
        _netcoreService.SendEmailBySendGridAsync(_sendGridOptions.SendGridKey,
            _sendGridOptions.FromEmail,
            _sendGridOptions.FromFullName,
            subject,
            message,
            email).Wait();
            
        return Task.CompletedTask;
    }
}

NetcoreService 类:

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);

}
4

0 回答 0