Click here to Skip to main content
15,890,438 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
im trying to edit data for the below sql 3 tables. using asp.net MVC please see website link for photo of the datatables
https://ibb.co/DWSHKwj


AspNetuser
Id = 100
Email = tim@yahoo.ca
Username = timmy

AspNetuserRole
UserId = 100
RoleID = 200

AspNetRole
Id = 200
Name = Admin
Discriminator = null


how would I edit the above table in the controller and view? I have the display details working but when i click the edit hyperlink I cant display the data.

edit page view and save:
Email = tim@yahoo.ca
UserName = timmy
Name = Admin

Save button

AspNetUser.Id should update into AspNetUserRole.UserID
AspNetRole.Id should update into AspNetUserRole.RoleID

What I have tried:

i cant find anything on this when searching
Posted
Updated 22-Aug-19 5:24am
v2

1 solution

Start with a view-model:
C#
public class UserViewModel
{
    public int Id { get; set; }
    public string EmailAddress { get; set; }
    public string Username { get; set; }
    public List<UserRoleViewModel> Roles { get; set; }
}

public class UserRoleViewModel
{
    public int RoleId { get; set; }
    public string RoleName { get; set; }
    public bool IsSelected { get; set; }
}
In the controller, you will need to populate the view-model:
C#
private void PopulateRoles(UserViewModel model)
{
    // Load all of the role names from the database:
    DataTable allRoles = ListAllRolesFromDatabase();
    
    // Convert the roles to the view-model:
    var roles = allRoles.AsEnumerable()
        .Select(r => new UserRoleViewModel 
        { 
            RoleId = r.Field<int>("Id"), 
            RoleName = r.Field<string>("Name") 
        })
        .ToDictionary(r => r.RoleId);
    
    if (model.Roles != null)
    {
        // We've posted back to the server - take the selected roles from the form:
        foreach (var role in model.Roles.Where(r => r.IsSelected))
        {
            if (roles.TryGetValue(role.RoleId, out var vm))
            {
                vm.IsSelected = true;
            }
        }
    }
    else if (model.Id != 0)
    {
        // We're editing an existing user - load their roles from the database:
        DataTable currentRoles = LoadRolesForUserFromDatabase(model.Id);
        foreach (DataRow row in currentRoles.Rows)
        {
            int id = row.Field<int>("Id");
            if (roles.TryGetValue(id, out var vm))
            {
                vm.IsSelected = true;
            }
        }
    }
    
    // Set the roles on the view-model:
    model.Roles = roles.Values.ToList();
}
Call that method before you display the add/edit view:
C#
[HttpGet]
public ActionResult Add()
{
    var model = new UserViewModel();
    PopulateRoles(model);
    return View(model);
}

[HttpPost, ValidateAntiForgeryToken]
public ActionResult Add(UserViewModel model)
{
    if (!ModelState.IsValid)
    {
        PopulateRoles(model);
        return View(model);
    }
    
    CreateUserAndAssignRolesInDatabase(model);
    return RedirectToAction(nameof(Index));
}

[HttpGet]
public ActionResult Edit(int id)
{
    DataRow row = LoadUserDetailsFromDatabase(id);
    if (row is null) return RedirectToAction(nameof(Index));
    
    var model = new UserViewModel
    {
        Id = row.Field<int>("Id"),
        EmailAddress = row.Field<string>("Email"),
        Username = row.Field<string>("Username"),
    };
    
    PopulateRoles(model);
    return View(model);
}

[HttpPost, ValidateAntiForgeryToken]
public ActionResult Edit(UserViewModel model)
{
    if (!ModelState.IsValid)
    {
        PopulateRoles(model);
        return View(model);
    }
    
    UpdateUserAndRolesInDatabase(model);
    return RedirectToAction(nameof(Index));
}
Then in your add/edit view, render a checkbox list for the roles - I'm using Bootstrap 4 here:
Razor
<div class="form-group row">
    <label class="col-form-label col-sm-3">Roles</label>
    <div class="col-sm">
        <ul class="list-unstyled">
        @for (int index = 0; index < Model.Roles.Count; index++)
        {
            <li>
                <div class="form-check mt-2">
                    @Html.HiddenFor(m => m.Roles[index].RoleId)
                    @Html.CheckBoxFor(m => m.Roles[index].IsSelected, new { @class = "form-check-input" })
                    @Html.LabelFor(m => m.Roles[index].IsSelected, Model.Roles[index].RoleName)
                </div>
            </li>
        }
        </ul>
    </div>
</div>
Now you just need to write the methods to load and save the view-model data to the database. Since you've already got the display working, I'll assume you already know how to do that. :)
 
Share this answer
 
v2
Comments
Maciej Los 22-Aug-19 11:47am    
5ed!
brantforthejim 26-Aug-19 8:54am    
i cant get DataTable
currentRoles = LoadRolesForUserFromDatabase(model.Id);
DataTable allRoles = ListAllRolesFromDatabase();
DataRow row = LoadUserDetailsFromDatabase(id);
to work. it highligts in red. what would i put here to make is work?

error does not exist in the current context
Richard Deeming 27-Aug-19 7:09am    
Those are methods you need to write, along with CreateUserAndAssignRolesInDatabase and UpdateUserAndRolesInDatabase.

As I said, since you've already got the display working, I've assumed you know how to write basic database access code.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900