admin管理员组文章数量:1435859
I have a little movie app, and it allows users to register and log in and add movie entries and add comments to the movie entries. But on the registration form, the email field is not correctly sending email addresses through and properly saving the email address in the database.
I have stepped through with the debugger and at this line in the
AccountController var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
I can see the username, email and password coming through successfully. But then at this line
if (identityResult.Succeeded)
{
I can see that identityResult
has failed. And at the bottom of that same Registration post method at this part
foreach (var error in identityResult.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
when I leave it like that, at the top of the Registration page it's showing up as the error
Email '' is invalid
I have also tried it like this:
foreach (var error in identityResult.Errors)
{
// ....
ModelState.AddModelError(string.Empty, user.Email);
}
When I try to sign up the user like that, I get the following at the top of the registration page: [email protected]
So I feel like something isn't correct in between these two lines:
var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
if (identityResult.Succeeded)
Here is my AccountController
:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using MovieOrganizer.Models.ViewModels;
using MovieOrganizer.Models.Domain;
namespace MovieOrganizer.Controllers
{
public class AccountController : Controller
{
private readonly UserManager<User> userManager;
private readonly SignInManager<User> signInManager;
public AccountController(UserManager<User> userManager,
SignInManager<User> signInManager)
{
this.userManager = userManager;
this.signInManager = signInManager;
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var user = new User
{
UserName = registerViewModel.UserName,
Email = registerViewModel.Email,
//PasswordHash = registerViewModel.Password
};
//var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
if (identityResult.Succeeded)
{
var roleIdentityResult = await userManager.AddToRoleAsync(user, "User");
if (roleIdentityResult.Succeeded)
{
//return RedirectToAction("Register");
await signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Movies");
}
}
else
{
foreach (var error in identityResult.Errors)
{
ModelState.AddModelError(string.Empty, user.Email);
}
}
return View(registerViewModel);
}
[HttpGet]
public IActionResult Login()
{
var model = new LoginViewModel
{
};
return View(model);
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel)
{
if (!ModelState.IsValid)
{
return View(loginViewModel);
}
var user = await userManager.FindByNameAsync(loginViewModel.UserName);
if (user == null)
{
// User not found
ModelState.AddModelError(string.Empty, "Invalid username.");
return View(loginViewModel);
}
var signInResult = await signInManager.PasswordSignInAsync(loginViewModel.UserName,
loginViewModel.Password, false, false);
if (signInResult != null && signInResult.Succeeded)
{
//if (!string.IsNullOrWhiteSpace(loginViewModel.ReturnUrl))
//{
// return Redirect(loginViewModel.ReturnUrl);
//}
return RedirectToAction("Index", "Movies");
}
if (signInResult.IsLockedOut)
{
ModelState.AddModelError(string.Empty, "User account locked out.");
}
else if (signInResult.IsNotAllowed)
{
ModelState.AddModelError(string.Empty, "User account not allowed.");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid password.");
}
return View(loginViewModel);
}
[HttpGet]
public async Task<IActionResult> Logout()
{
await signInManager.SignOutAsync();
return RedirectToAction("Index", "Home");
}
[HttpGet]
public IActionResult AccessDenied()
{
return View();
}
}
}
Here is my RegisterViewModel
:
using System.ComponentModel.DataAnnotations;
namespace MovieOrganizer.Models.ViewModels
{
public class RegisterViewModel
{
[Required]
public string UserName { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[MinLength(6, ErrorMessage = "Password has to be at least 6 characters")]
public string Password { get; set; }
}
}
and here is my Register.cshtml
view:
@model MovieOrganizer.Models.ViewModels.RegisterViewModel
<h1>Sign Up for Movie Library</h1>
@if (ViewData.ModelState.IsValid == false && ViewData.ModelState.ErrorCount > 0)
{
foreach (var error in ViewData.ModelState.Values.SelectMany(v => v.Errors))
{
<p class="error">@error.ErrorMessage</p>
}
}
<div class="container mx-auto">
<div class="row justify-content-center">
<div class="col-12 col-lg-6">
<h1 class="mt-3 mb-3 h3">
Register
</h1>
<form method="post">
<div class="mb-3">
<label class="form-label">Username</label>
<input type="text" id="username" class="form-control" asp-for="UserName" registered />
<span class="text-danger" asp-validation-for="UserName"></span>
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" id="email" class="form-control" asp-for="Email" required />
<span class="text-danger" asp-validation-for="Email"></span>
</div>
<div class="mb-3">
<label class="form-label">Password</label>
<input type="password" id="password" class="form-control" asp-for="Password" required minlength="6" />
<span class="text-danger" asp-validation-for="Password"></span>
</div>
<div class="mb-3">
<label class="form-label">Password Confirmation</label>
<input type="password" id="PasswordConfirmation" name="PasswordConfirmation" class="form-control" asp-for="Password" required minlength="6" />
<span class="text-danger" asp-validation-for="Password"></span>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-dark">Register</button>
</div>
</form>
</div>
<h4><a href="/auth/google_oauth2">Log in with Google</a></h4>
</div>
</div>
This is my Program.cs
file:
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using MovieOrganizer.Data;
using MovieOrganizer.Models.Domain;
using MovieOrganizer.Repositories;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<MovieDBContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("MovieOrganizerCon")));
builder.Services.AddIdentity<User, IdentityRole<Guid>>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<MovieDBContext>()
.AddDefaultTokenProviders();
//builder.Services.AddIdentity<IdentityUser, IdentityRole>()
// .AddEntityFrameworkStores<MovieDBContext>();
builder.Services.AddScoped<IMovieRepository, MovieRepository>();
builder.Services.AddScoped<IMovieLogRepository, MovieLogRepository>();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
builder.Services.AddScoped<UserManager<User>>();
builder.Services.AddScoped<SignInManager<User>>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole<Guid>>>();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
string[] roleNames = { "User" };
foreach(var roleName in roleNames)
{
var roleExist = await roleManager.RoleExistsAsync(roleName);
if (!roleExist)
{
await roleManager.CreateAsync(new IdentityRole<Guid>(roleName));
}
}
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Movies}/{action=Index}/{id?}");
app.Run();
I have a little movie app, and it allows users to register and log in and add movie entries and add comments to the movie entries. But on the registration form, the email field is not correctly sending email addresses through and properly saving the email address in the database.
I have stepped through with the debugger and at this line in the
AccountController var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
I can see the username, email and password coming through successfully. But then at this line
if (identityResult.Succeeded)
{
I can see that identityResult
has failed. And at the bottom of that same Registration post method at this part
foreach (var error in identityResult.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
when I leave it like that, at the top of the Registration page it's showing up as the error
Email '' is invalid
I have also tried it like this:
foreach (var error in identityResult.Errors)
{
// ....
ModelState.AddModelError(string.Empty, user.Email);
}
When I try to sign up the user like that, I get the following at the top of the registration page: [email protected]
So I feel like something isn't correct in between these two lines:
var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
if (identityResult.Succeeded)
Here is my AccountController
:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using MovieOrganizer.Models.ViewModels;
using MovieOrganizer.Models.Domain;
namespace MovieOrganizer.Controllers
{
public class AccountController : Controller
{
private readonly UserManager<User> userManager;
private readonly SignInManager<User> signInManager;
public AccountController(UserManager<User> userManager,
SignInManager<User> signInManager)
{
this.userManager = userManager;
this.signInManager = signInManager;
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var user = new User
{
UserName = registerViewModel.UserName,
Email = registerViewModel.Email,
//PasswordHash = registerViewModel.Password
};
//var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
var identityResult = await userManager.CreateAsync(user, registerViewModel.Password);
if (identityResult.Succeeded)
{
var roleIdentityResult = await userManager.AddToRoleAsync(user, "User");
if (roleIdentityResult.Succeeded)
{
//return RedirectToAction("Register");
await signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Movies");
}
}
else
{
foreach (var error in identityResult.Errors)
{
ModelState.AddModelError(string.Empty, user.Email);
}
}
return View(registerViewModel);
}
[HttpGet]
public IActionResult Login()
{
var model = new LoginViewModel
{
};
return View(model);
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel)
{
if (!ModelState.IsValid)
{
return View(loginViewModel);
}
var user = await userManager.FindByNameAsync(loginViewModel.UserName);
if (user == null)
{
// User not found
ModelState.AddModelError(string.Empty, "Invalid username.");
return View(loginViewModel);
}
var signInResult = await signInManager.PasswordSignInAsync(loginViewModel.UserName,
loginViewModel.Password, false, false);
if (signInResult != null && signInResult.Succeeded)
{
//if (!string.IsNullOrWhiteSpace(loginViewModel.ReturnUrl))
//{
// return Redirect(loginViewModel.ReturnUrl);
//}
return RedirectToAction("Index", "Movies");
}
if (signInResult.IsLockedOut)
{
ModelState.AddModelError(string.Empty, "User account locked out.");
}
else if (signInResult.IsNotAllowed)
{
ModelState.AddModelError(string.Empty, "User account not allowed.");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid password.");
}
return View(loginViewModel);
}
[HttpGet]
public async Task<IActionResult> Logout()
{
await signInManager.SignOutAsync();
return RedirectToAction("Index", "Home");
}
[HttpGet]
public IActionResult AccessDenied()
{
return View();
}
}
}
Here is my RegisterViewModel
:
using System.ComponentModel.DataAnnotations;
namespace MovieOrganizer.Models.ViewModels
{
public class RegisterViewModel
{
[Required]
public string UserName { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[MinLength(6, ErrorMessage = "Password has to be at least 6 characters")]
public string Password { get; set; }
}
}
and here is my Register.cshtml
view:
@model MovieOrganizer.Models.ViewModels.RegisterViewModel
<h1>Sign Up for Movie Library</h1>
@if (ViewData.ModelState.IsValid == false && ViewData.ModelState.ErrorCount > 0)
{
foreach (var error in ViewData.ModelState.Values.SelectMany(v => v.Errors))
{
<p class="error">@error.ErrorMessage</p>
}
}
<div class="container mx-auto">
<div class="row justify-content-center">
<div class="col-12 col-lg-6">
<h1 class="mt-3 mb-3 h3">
Register
</h1>
<form method="post">
<div class="mb-3">
<label class="form-label">Username</label>
<input type="text" id="username" class="form-control" asp-for="UserName" registered />
<span class="text-danger" asp-validation-for="UserName"></span>
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" id="email" class="form-control" asp-for="Email" required />
<span class="text-danger" asp-validation-for="Email"></span>
</div>
<div class="mb-3">
<label class="form-label">Password</label>
<input type="password" id="password" class="form-control" asp-for="Password" required minlength="6" />
<span class="text-danger" asp-validation-for="Password"></span>
</div>
<div class="mb-3">
<label class="form-label">Password Confirmation</label>
<input type="password" id="PasswordConfirmation" name="PasswordConfirmation" class="form-control" asp-for="Password" required minlength="6" />
<span class="text-danger" asp-validation-for="Password"></span>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-dark">Register</button>
</div>
</form>
</div>
<h4><a href="/auth/google_oauth2">Log in with Google</a></h4>
</div>
</div>
This is my Program.cs
file:
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using MovieOrganizer.Data;
using MovieOrganizer.Models.Domain;
using MovieOrganizer.Repositories;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<MovieDBContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("MovieOrganizerCon")));
builder.Services.AddIdentity<User, IdentityRole<Guid>>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<MovieDBContext>()
.AddDefaultTokenProviders();
//builder.Services.AddIdentity<IdentityUser, IdentityRole>()
// .AddEntityFrameworkStores<MovieDBContext>();
builder.Services.AddScoped<IMovieRepository, MovieRepository>();
builder.Services.AddScoped<IMovieLogRepository, MovieLogRepository>();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
builder.Services.AddScoped<UserManager<User>>();
builder.Services.AddScoped<SignInManager<User>>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole<Guid>>>();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
string[] roleNames = { "User" };
foreach(var roleName in roleNames)
{
var roleExist = await roleManager.RoleExistsAsync(roleName);
if (!roleExist)
{
await roleManager.CreateAsync(new IdentityRole<Guid>(roleName));
}
}
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Movies}/{action=Index}/{id?}");
app.Run();
Share
Improve this question
edited Nov 15, 2024 at 19:24
marc_s
757k184 gold badges1.4k silver badges1.5k bronze badges
asked Nov 15, 2024 at 19:10
braddbradd
14 bronze badges
1
- Have you stepped through CreateAsync()? – Ross Bush Commented Nov 15, 2024 at 19:14
1 Answer
Reset to default 0Does your password break the rules you configured in program.cs?
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
If not ,you could add the codes below to check the detailed error message
if (identityResult.Succeeded)
{
......
}
else
{
var exceptionText = identityResult.Errors.Aggregate("Identity Errors : \n\r\n\r", (seed, error) => seed + (" - " + error + "\n\r"));
//log the error or throw exception
.........
}
本文标签: cCorrectly save email field through registration form in ASPNET Core MVC appStack Overflow
版权声明:本文标题:c# - Correctly save email field through registration form in ASP.NET Core MVC app - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745675311a2669815.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论