5

I already have a register action

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
            var useremail = _userManager.Users.FirstOrDefault(u => u.Email.ToLower() == Input.Email.ToLower());

            if (useremail == null)
            {
                returnUrl = returnUrl ?? Url.Content("~/");
                ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

                if (ModelState.IsValid)
                {
                    var user = new IdentityUser { UserName = Input.UserName, Email = Input.Email };
                    var result = await _userManager.CreateAsync(user, Input.Password);
                    if (result.Succeeded)
                    {
                        _logger.LogInformation("User created a new account with password.");

                        var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                        code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
                        var callbackUrl = Url.Page(
                            "/Account/ConfirmEmail",
                            pageHandler: null,
                            values: new { area = "Identity", 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>.");

                        if (_userManager.Options.SignIn.RequireConfirmedAccount)
                        {
                            return RedirectToPage("RegisterConfirmation", new { email = Input.Email });
                        }
                        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
            ViewData["EmailExists"] = "Try another email that one is used";

            return Page();
}

Then I created the sendgrid user and key and registered them by CMD, then I created the action of send email

public class EmailSender : IEmailSender
{
        public EmailSender(IOptions<AuthMessageSenderOptions>optionsAccessor)
        {
            Options = optionsAccessor.Value;
        }

        public AuthMessageSenderOptions Options { get; }

        public Task SendEmailAsync (string email , string subject , string message)
        {
            return Excute(Options.SendGridKey,subject,message,email);
        }

        private Task Excute(string apiKey, string subject, string message, string email)
        {
            var client = new SendGridClient(apiKey);
            var msg = new SendGridMessage()
            {
                From = new EmailAddress("[email protected]", "dary dress"),
                Subject = subject,
                PlainTextContent = message,
                HtmlContent = message
            };

            msg.AddTo(new EmailAddress(email));
            msg.SetClickTracking(false, false);

            return client.SendEmailAsync(msg);
        }
}

Then in startup.cs

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
          options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
    services.AddIdentity<IdentityUser, IdentityRole>( options => options.SignIn.RequireConfirmedAccount = true)
                .AddDefaultUI()
                .AddDefaultTokenProviders()
                .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddControllersWithViews();
    services.AddRazorPages();
    services.AddMvc();
    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);
    services.AddPaging();
    services.ConfigureApplicationCookie(o => {
                o.ExpireTimeSpan = TimeSpan.FromDays(5);
                o.SlidingExpiration = true;
            });
    services.AddMvc(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
            });
    services.ConfigureApplicationCookie(options =>
            {
                options.AccessDeniedPath = new Microsoft.AspNetCore.Http.PathString("/Main/AccessDenied");
            });
}

but sending an e-mail doesn't work after registration gives me some words that i need confirm my email and gives me link to confirm my email but doesn't send it to gmail

Does anyone have an idea?

I followed this documentation from microsoft https://learn.microsoft.com/en-us/aspnet/core/security/authentication/accconfirm?view=aspnetcore-3.1&tabs=visual-studio

2
  • i Added Environment with user and key for sendgrid from properities - Debug and when i register again redirect me to this view This app does not currently have a real email sender registered, see these docs for how to configure a real email sender. Normally this would be emailed: Click here to confirm your account Commented Apr 3, 2020 at 17:10
  • Please tell us more about how you are measuring "doesn't work". Which system "gives the link to confirm my email"? This may be a question for SendGrid support. Commented Apr 3, 2020 at 22:15

2 Answers 2

12

When I create a new web application with individual user accounts, this works perfectly, but I noticed that when you scaffold identity and override all pages to have control into an existing app, the behavior you are experiencing is the usual.

Here is how I fixed it:

If you open the file Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs look for the comment Once you add a real email sender, you should remove this code that lets you confirm the account, comment everything below that line before the return Page() statement and that should do the job.

Sign up to request clarification or add additional context in comments.

12 Comments

You tested it, works for you after commenting that part below that line "Once you add a real email sender, you should remove this code"
Correct, now, are you working with external login like Google or Microsoft?
No i don't l, but still dosen't work that makes me redirect to view check your email to confirm your account
I have a question do i need a domain to makes the emails received at gmail ? I haven't, someonw told me that i need it to make in sendgrid sender authentication get start
I don't have a domain and it did work, tell me something, when you added the secrets for SendGridUser, did you use your username under account details in UserGrid portal?
|
1

"Solved" I asked Sendgrid, and I was told that I cannot use my yahoo email (or gmail,...) as the sender email; this is part of the answer: "Yahoo observes an email security standard called DMARC. DMARC instructs email providers to reject messages where the From domain is a Yahoo domain, but the message originates from a non-approved domain server/service." So I need to use my own mail domain;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.