I am working with a View
that returns List<ViewModel>
to the Controller
's Create
action method.
Questions:
- Is it correct to return
List<ViewModel>
to the controller? The reason I am doing is that I have to make multiple rows entry to the DB for each user. 2. MyController
implemenation is incorrect because I am trying to add data through single User object where I have recieved List of ViewModels which is only the representation of the View for single user. So how the controller should be implemented? - Do I need to have a
public ActionResult Create()
method in the controller?
Limitations:
- Can't change database
- None of the User or Role table in the database has int type
PK
Logic:
User would be able to select multiple checkboxes(represents ROLE) for each user and that should be persisted in the database as single row. For example
DB: dbo.User table should have the following entries on Save
(abcdefg, levelA, locationB, Role2, null, null, Y)
(msjdhcdu, levelA, locationB, Role2, null, null, Y) Same user Different Role
(msjdhcdu, levelA, locationB, Role3, null, null, Y) Same user Different Role
USer would be kept on the same page (save VIEW) after the Save button click and showing the recent changes in the database.
ViewModel:
public class UserViewModel
{
public string UserName { get; set; }
public string Level { get; set; }
public string Location { get; set; }
public List<RoleViewModel> Roles { get; set; }
}
public class RoleViewModel
{
public string RoleName{ get; set; }
public bool IsSelected { get; set; }
}
View: I might be doing something very wrong in the VIEW
@model List<Project.ViewModels.UserViewModel>
@using (@Html.BeginForm("Create", "User", FormMethod.Post ,new { id = "UserPermissionForm" }))
{
<table class="table">
<tr>
<th>User</th>
@for (int i = 0; i < Model[0].Roles.Count; i++)
{
<th>
@Model[0].Roles[i].RoleName
</th>
}
</tr>
@for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(m => m[i].UserName)
@Model[i].UserName
</td>
@for (int j = 0; j < Model[i].Roles.Count; j++)
{
<td>
@Html.CheckBoxFor(m => m[i].Roles[j].IsSelected)
</td>
}
</tr>
}
</table>
<div class="form-actions">
<button type="submit" class="btn btn-success submit" value="Save">Save changes</button>
</div>
<script>
$('#Submit').click(function () {
let url = '@Url.Action("Create", "Users")'
$.post(url, $("#UserPermissionForm"))
});
</script>
Controller:
[HttpPost]
public ActionResult Create(List<UserViewModel> viewModelList)
{
for (int i= 0; i > viewModelList.Count; i++) {
for (int j = 0; j > viewModelList[i].Roles.Count; j++) {
db.UserDetails.Add(new User
{
username = viewModelList[i].UserName,
level = viewModelList[i].Level,
location = viewModelList[i].Location,
role = viewModelList[i].Roles[j].RoleName,
Approval = "",
Request = "",
Active = "Y"
});
}
db.SaveChanges();
return RedirectToAction("Index","Users");
}
return View(viewModelList); // not right
}
Error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[Project.ViewModels.UserViewModel]', but this dictionary requires a model item of type 'Project.Models.User'.
Any guidance/help is appreciated.
EDIT1: View has been added EDIT2: Bsuiness logic added