Im just starting ASP.NET 5 Core MVC. I used identity for register. When I submit the register form, Model.isValid returns false in the post of razor page. The only thing that gets posted is the dropdown Item, all others are null. If I remove the role dropdown from the register and then submit it works fine.(Input.Name is the role)
namespace SoftcodeWebGem.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterModel : PageModel
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
private readonly RoleManager<IdentityRole> _roleManager;
public RegisterModel(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender,
RoleManager<IdentityRole> roleManager)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
_roleManager = roleManager;
}
[BindProperty]
public InputModel Input { get; set; }
public string ReturnUrl { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public class InputModel
{
[Required]
[DataType(DataType.Text)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public string Name { get; set; }
}
//public void OnGet(string returnUrl = null)
//{
// ViewData["roles"] = _roleManager.Roles.ToList();
// ReturnUrl = returnUrl;
//}
public async Task OnGetAsync(string returnUrl = null)
{
ViewData["roles"] = _roleManager.Roles.ToList();
ReturnUrl = returnUrl;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
var role = _roleManager.FindByIdAsync(Input.Name).Result;
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.");
await _userManager.AddToRoleAsync(user, role.Name);
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);
}
ViewData["roles"] = _roleManager.Roles.ToList();
}
// If we got this far, something failed, redisplay form
return Page();
}
}
The below code is the Select element
@page
@model RegisterModel
@{
ViewData["Title"] = "Register";
var roles = (List<IdentityRole>)ViewData["roles"];
}
<div class="container">
<div style="padding-top:80px;"></div>
<div class="container pt-5 pb-3" style="background-color: white;
width:500px; height:auto; border-radius:10px;">
<div class="text-center">
<h3>Softcode Gem Solution</h3>
<h6><img src="~/images/icons/add_user_male_32px.png" alt="Register" />Register with your Credentials</h6>
</div>
<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
@Html.AntiForgeryToken()
<div class="form-floating mb-3 ">
<input asp-for="Input.FirstName" type="text" class="form-control" id="firstname" name="firstname" placeholder="First Name" style="border-radius: 5px; ">
<label asp-for="Input.FirstName"><img src="~/images/icons/name_24px.png" />First Name</label>
<span asp-validation-for="Input.FirstName" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.LastName" type="text" class="form-control" id="lastname" name="lastname" placeholder="Last Name" style="border-radius: 5px; ">
<label asp-for="Input.LastName"><img src="~/images/icons/name_24px.png" />Last Name</label>
<span asp-validation-for="Input.LastName" class="text-danger"></span>
</div>
<div class="form-floating mb-3">
<input asp-for="Input.Email" type="email" class="form-control" id="email" name="email" placeholder="Email" style="border-radius: 5px; ">
<label asp-for="Input.Email"><img src="~/images/icons/email_24px.png" />Email address</label>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-floating mb-3 pb-2">
<input asp-for="Input.Password" type="password" class="form-control" id="password" name="password" placeholder="Password" style="border-radius: 5px;">
<label asp-for="Input.Password"><img src="~/images/icons/password_24px.png" />Password</label>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-floating mb-3 pb-2">
<input asp-for="Input.ConfirmPassword" type="password" class="form-control" id="confirmpassword" name="confirmpassword" placeholder="Confirm Password" style="border-radius: 5px;">
<label asp-for="Input.ConfirmPassword"><img src="~/images/icons/password_24px.png" />Confirm Password</label>
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<div class="form-control mb-3 pb-2">
<label asp-for="Input.Name"></label>
<select asp-for="Input.Name" class="form-control" asp-items='new SelectList((List<IdentityRole>)ViewData["roles"], "Id", "Name")'></select>
<span asp-validation-for="Input.Name" class="text-danger"></span>
</div>
<button class="w-100 btn btn-lg btn-primary " type="submit">Register</button>
<a asp-page="./Login" asp-route-returnUrl="@Model.ReturnUrl" style="text-decoration:none;"><p class="mt-3 mb-2 text-muted ">Already Registered? Login</p></a>
</form>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
There are many questions similar to this but none of them use identity or that what I found. Please help
2
Answers
fix action OnGetAsync, add Roles
and view
And I can’t see your Input but something tells me that instead of Input.Name you have to use Input.Id or create it.
In your code it looks like there is a conflict in
Name
as in yourRegister.chtml
First change the
public string Name { get; set; }
code in theRegisterModel
toThen look at this part of your code
input.Name
and the Name in theSelectList
:Just try changing to this:
`