I am using MVC to build a website. On this current view, admin can select 1 users and 1 role to assign to the selected users. I am having trouble obtaining the list of selected users. I am using a model to display all the users and their current roles, so there are no properties that save data from the form. Here is the form within the view ManageRoles.cshtml :
@using IssueTracker.Areas.Identity.Data;
@model List<UserRoleViewModel>
@{
ViewData["Title"] = "Manage User Roles";
}
@section Scripts2
{
<link rel="stylesheet" href="../../dist/plugins/select2/css/select2.min.css">
<link rel="stylesheet" href="../../dist/plugins/sweetalert2-theme-bootstrap-4/bootstrap-4.min.css">
<link rel="stylesheet" href="../../dist/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css">
<link rel="stylesheet" href="../../dist/plugins/datatables-responsive/css/responsive.bootstrap4.min.css">
<link rel="stylesheet" href="../../dist/plugins/datatables-buttons/css/buttons.bootstrap4.min.css">
}
<div >
<div >
<div >
<div >
<h3 >
Change or Update User Roles
</h3>
</div>
<div >
<form method="post">
<div >
<label>Select 1 or More Users:</label>
<div >
<select name="userList" multiple="multiple" data-dropdown-css- data-placeholder="Select a User" style="width: 100%;">
@if (Model.Any())
{
foreach (var user in Model)
{
<option [email protected]>@user.userName</option>
}
}
</select>
</div>
</div>
<div >
<label for="inputRole">Select the Role to Assign:</label>
<select name="roleName" id="inputRole" >
<option selected disabled>N/A</option>
<option value="Admin">Admin</option>
<option value="Developer">Developer</option>
<option value="Project Manager">Project Manager</option>
<option value="Submitter">Submitter</option>
<option value="Demo Admin">Demo Admin</option>
<option value="Demo Developer">Demo Developer</option>
<option value="Demo Project Manager">Demo Project Manager</option>
<option value="Demo Submitter">Demo Submitter</option>
</select>
</div>
<div >
<div >
<input asp-controller="Home" asp-action="ManageRoles" type="submit" value="Change Role" >
</div>
</div>
</form>
</div>
</div>
</div>
<div >
<div >
<div >
<h3 >
Current Personnel
</h3>
</div>
<div >
<table id="example1" aria-describedby="example1_info">
<thead>
<tr>
<th tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-sort="ascending" aria-label="User: activate to sort column descending">User</th>
<th tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-label="Role: activate to sort column ascending" style="">Role</th>
</tr>
</thead>
<tbody>
@if (Model.Any())
{
foreach (var user in Model)
{
<tr >
<td tabindex="0">@user.userName</td>
<td style="">@user.roleNames</td>
</tr>
}
}
</tbody>
<tfoot>
<tr>
<th rowspan="1" colspan="1">User</th>
<th rowspan="1" colspan="1" style="">Role</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
@section Scripts{
<script src="../../dist/plugins/select2/js/select2.full.min.js"></script>
<script src="../../dist/plugins/sweetalert2/sweetalert2.min.js"></script>
<script>$(function () {
$('.select2').select2()
$('#mySelect2').find(':selected');
})</script>
<script>$(function () {
var Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000
});
$('.swalDefaultSuccess').click(function () {
Toast.fire({
icon: 'success',
title: "Ryan Tobin's role has been changed to Admin."
})
});
});</script>
<script src="../../dist/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="../../dist/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js"></script>
<script src="../../dist/plugins/datatables-responsive/js/dataTables.responsive.min.js"></script>
<script src="../../dist/plugins/datatables-responsive/js/responsive.bootstrap4.min.js"></script>
<script src="../../dist/plugins/datatables-buttons/js/dataTables.buttons.min.js"></script>
<script src="../../dist/plugins/datatables-buttons/js/buttons.bootstrap4.min.js"></script>
<script src="../../dist/plugins/jszip/jszip.min.js"></script>
<script src="../../dist/plugins/pdfmake/pdfmake.min.js"></script>
<script src="../../dist/plugins/pdfmake/vfs_fonts.js"></script>
<script src="../../dist/plugins/datatables-buttons/js/buttons.html5.min.js"></script>
<script src="../../dist/plugins/datatables-buttons/js/buttons.print.min.js"></script>
<script src="../../dist/plugins/datatables-buttons/js/buttons.colVis.min.js"></script>
<script>$(function () {
$("#example1").DataTable({
"responsive": true, "lengthChange": false, "autoWidth": false,
}).buttons().container().appendTo('#example1_wrapper .col-md-6:eq(0)');
});</script>
}
Here is the controller:
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using IssueTracker.Models;
using Microsoft.AspNetCore.Authorization;
using IssueTracker.Areas.Identity.Data;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
namespace IssueTracker.Controllers;
[Authorize]
public class HomeController : Controller
{
private IssueTrackerIdentityDbContext application;
private UserManager<ApplicationUser> userManager;
private RoleManager<IdentityRole> roleManager;
public HomeController(IssueTrackerIdentityDbContext app, UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager)
{
application = app;
this.userManager = userManager;
this.roleManager = roleManager;
}
public IActionResult Index()
{
return View();
}
[Authorize(Roles = "Admin,Demo Admin")]
public IActionResult ManageRoles()
{
var model = new List<UserRoleViewModel>();
foreach (var user in userManager.Users)
{
var roleList = userManager.GetRolesAsync(user).Result;
var roles = string.Join(", ", roleList);
var userRoleViewModel = new UserRoleViewModel
{
userName = user.FirstName " " user.LastName,
roleNames = roles
};
model.Add(userRoleViewModel);
}
return View(model);
}
[HttpPost]
public async Task<IActionResult> ManageRoles(List<string> userList, string roleName)
{
foreach (string userName in userList)
{
ApplicationUser user = await userManager.FindByNameAsync(userName);
var roles = await userManager.GetRolesAsync(user);
await userManager.RemoveFromRolesAsync(user, roles.ToArray());
await userManager.AddToRoleAsync(user, roleName);
}
return RedirectToAction("ManageRoles");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
and here is the model UserRoleViewModel.cs being used:
using System;
namespace IssueTracker.Models
{
public class UserRoleViewModel
{
public String userName { get; set; }
public String roleNames { get; set; }
}
}
I understand that the name property can be used within the form (I used that to successfully obtain the selected role); however, I am not sure how to use that for the select2 list. How can I obtain a list of the selected options and send that to the controller to parse into ApplicationUsers. Thank you!
CodePudding user response:
In this case you will need to add a name tag as name='userList'
and modify the list parameter in ManageRoles method to List<String> userList
.
Any inputs in the form you want to submit need to have a name and it needs to be the same as the param name in you're controller.
And the list change is because when you select a value, the value is an string not the view model. <option [email protected]>
Hope this helps :)