Background
This question is a continuation of my previous question. In that question, I've faced a problem where I could not log in to an existing user. I solved it thanks to Md Farid Uddin Kiron. I have changed my connection string in the appsettings.json
. It solved my problem but now I have another problem.
Question/Problem
I am facing an unusual problem, when I try to create a new account I get an exception that says that the username already exists. I have only one user with a unique username (email address). I can't understand why it is happening.
I am adding the function that handles the signup process, but I don't believe the problem comes from it.
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = Input.Email,
Email = Input.Email,
FirstName = Input.FirstName,
LastName = Input.LastName
};
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, returnUrl = returnUrl },
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, 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();
}
CreateAsync
//
// Summary:
// Creates the specified user in the backing store with given password, as an asynchronous operation.
//
// Parameters:
// user:
// The user to create.
//
// password:
// The password for the user to hash and store.
//
// Returns:
// The System.Threading.Tasks.Task that represents the asynchronous operation, containing
// the Microsoft.AspNetCore.Identity.IdentityResult of the operation.
public virtual Task<IdentityResult> CreateAsync(TUser user);
[AsyncStateMachine(typeof(UserManager<>.<CreateAsync>d__78))]
public virtual Task<IdentityResult> CreateAsync(TUser user, string password);
If you need more code do not be afraid to ask for it.
Thanks for your time.
Alright, with the help of Cetin Basoz we have solved the issue, here is a step-by-step guide to how we solved it.
We created a zoom meeting where we went through the code and debuted it step by step. One thing that popped up while we were in zoom was that some columns in the SQL table could not be null. Then I realized that the version of the solution did not match up with the SQL table of users, meaning, that on the laptop I used an older code that did not have some of the requirements to run with the SQL table.
After we fixed the SQL errors I found out that my laptop was missing the API key that is used to send email confirmations. My API key was saved as an environment variable on my main PC. This is a problem because if I would want to upload my code to the web, it would not be able to send emails because the API key will be missing.
To solve this, I wanted to put the key inside my code, but by doing this I realized that people would have access to it. To save it somewhere "more" safe I saved it in my Resources.resx
file and access it like this:
public string APIKey { get; }
public EmailSender()
{
this.APIKey = Properties.Resources.SendGridAPIKey; // Access right here.
}