Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Many to many in asp.net mvc view and controller

How do I handle a many to many object mapping in the view and controller in the context of users and roles?

I used entity framework to map to pure POCOs like this:

public class Role
{
    public int RoleId { get; set; }
    public string RoleName { get; set; }
    public List<User> Users { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public List<Role> Roles { get; set; }
}

In my view, I'd like to add a User to a role using checkboxes. I list all the roles then check one to add the user to that role. How do I handle this?

like image 741
Shawn Mclean Avatar asked Jan 10 '11 19:01

Shawn Mclean


People also ask

Can I send multiple view models to a view from controller?

In MVC we cannot pass multiple models from a controller to the single view.

Can a view have multiple models?

Yes, you can use Tuple (brings magic in view having multiple model).

How many ways we can pass data from view to controller?

This blog will discuss four (4) common ways to pass data from the view to the controller: Passing by Typed Arguments. Request Object. Form Collections Object.

Can we have multiple views for single controller?

Yes You can use multiple View in one Controller.


1 Answers

I would start by designing a view model for this scenario:

public class UserRolesViewModel
{
    public int UserId { get; set; }
    public IEnumerable<RoleViewModel> Roles { get; set; }
}

public class RoleViewModel
{
    public int RoleId { get; set; }
    public bool InRole { get; set; }
    public string RoleName { get; set; }
}

Then a roles controller:

public class RolesController : Controller
{
    public ActionResult Edit(int userId)
    {
        // TODO: Use a repository to fetch the roles associated to the given
        // user id and then AutoMapper to map your model POCOs 
        // to a UserRolesViewModel
        var model = new UserRolesViewModel
        {
            UserId = userId,
            Roles = new[]
            {
                new RoleViewModel { RoleId = 1, InRole = false, RoleName = "Role 1" },
                new RoleViewModel { RoleId = 2, InRole = true, RoleName = "Role 2" },
                new RoleViewModel { RoleId = 3, InRole = true, RoleName = "Role 3" }
            }
        };
        return View(model);
    }

    [HttpPut]
    public ActionResult Update(UserRolesViewModel model)
    {
        // Here you will get the view model back containing the
        // user id and the selected roles
        // TODO: use AutoMapper to map back to a POCO and 
        // invoke the repository to update the database
        return RedirectToAction("Edit");
    }
}

then the Edit view (~/Views/Roles/Edit.cshtml):

@model YourAppName.Models.UserRolesViewModel
@{
    ViewBag.Title = "Edit user roles";
}
<h2>Roles for user @Model.UserId</h2>
@using (Html.BeginForm("Update", "Roles"))
{
    @Html.HttpMethodOverride(HttpVerbs.Put)
    @Html.HiddenFor(x => x.UserId)
    @Html.EditorFor(x => x.Roles)
    <input type="submit" value="update roles" />
}

and finally the corresponding editor template (~/Views/Roles/EditorTemplates/RoleViewModel.cshtml):

@model YourAppName.Models.RoleViewModel
<div>
    @Model.RoleName
    @Html.HiddenFor(x => x.RoleId)
    @Html.CheckBoxFor(x => x.InRole)
</div>
like image 156
Darin Dimitrov Avatar answered Oct 15 '22 21:10

Darin Dimitrov