Search code examples
c#asp.net-core.net-coreasp.net-identityrazor-pages

Razor View is passing wrong Id to OnPost method


I am using Asp.net Core .Net 5 Web app with Razor pages and Identity. I want to build a Role Manager page for Admin, but when assigning role to a user the passed roleId from View doesn't match the roleId that I passed into View. Here is my Model

public class RoleManagerModel : PageModel
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<IdentityRole> _roleManager;

    public RoleManagerModel(UserManager<ApplicationUser> userManager,
        RoleManager<IdentityRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }

    public IEnumerable<ApplicationUser> Users { get; set; }
    public IEnumerable<IdentityRole> Roles { get; set; }


    public ApplicationUser UserToChangeRole { get; set; }
    [BindProperty]
    public IdentityRole RoleToAssign { get; set; }
    public static string FirstID { get; set; }
    public static string SecondId { get; set; }

    public async Task OnGet()
    {
        Users = await _userManager.Users.ToListAsync();
        Roles = await _roleManager.Roles.ToListAsync();
        FirstID = Roles.FirstOrDefault(r => r.Name == "Admin").Id;

    }

    public async Task<IActionResult> OnPost(string userId)
    {
        UserToChangeRole = await _userManager.FindByIdAsync(userId);
        SecondId = RoleToAssign.Id;
        if(FirstID == SecondId)
        {
            string Gogo = "true";
        }
        var role = await _roleManager.FindByIdAsync(RoleToAssign.Id);
        if (UserToChangeRole == null)
            RedirectToPage("/Identity/NotFound");
        if (await _roleManager.RoleExistsAsync(RoleToAssign.Name))
        {
           await  _userManager.AddToRoleAsync(UserToChangeRole, RoleToAssign.Name);
        }

        Users = await _userManager.Users.ToListAsync();
        Roles = await _roleManager.Roles.ToListAsync();

        return Page();
    }

And here is the form in my view.

 <!--Roles-->
            <td>
                <form method="post">

                    <div class="form-group">
                        <label asp-for="Roles"></label>
                        <select class="form-control" asp-for="RoleToAssign">
                            @foreach (var role in Model.Roles)
                            {
                                <option value="@role.Id">@role.Name</option>
                            }
                        </select>

                    </div>

                    <button type="submit" class="btn btn-primary btn-sm">Assign</button>
                    <input type="hidden" name="userId" value="@user.Id" />
                </form>

            </td>

As you can see in the Post method I perform a check if passed and received roleIds match. They don't. What am I doing wrong? Any suggestions? Thanks.


Solution

  • Add to page model

     [BindProperty]
     public int RoleToAssignId { get; set; }
    

    and view

    <select class="form-control" asp-for="RoleToAssignId">
     @foreach (var role in Model.Roles)
     {
      <option value="@role.Id">@role.Name</option>
     }
    </select>