skip to Main Content

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

}
ScreenShot of The Debug

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


  1. fix action OnGetAsync, add Roles

    ....
     ViewBag.Roles = _roleManager.Roles.Select (i=> new SelectListItem {
        Value= i.Id.ToString(),
        Text= i.Name
       }).ToList();
    ....
    
    

    and view

     <select asp-for="Input.Name" class="form-control" asp-items="@ViewBag.Roles"></select>
    

    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.

    Login or Signup to reply.
  2. In your code it looks like there is a conflict in Name as in your Register.chtml

    First change the public string Name { get; set; } code in the RegisterModel to

    [Display(Name = "User Role")] 
    public string UserRole { get; set; }
    

    Then look at this part of your code input.Name and the Name in the SelectList:

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

    Just try changing to this:

    <div class="form-control mb-3 pb-2">
         <label asp-for="Input.UserRole"></label>
         <select asp-for="Input.UserRole" class="form-control" asp-items='new SelectList((List<IdentityRole>)ViewData["roles"], "Id", "Name")'></select>
         <span asp-validation-for="Input.UserRole" class="text-danger"></span>
    </div>
    

    `

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search