Reputation: 333
I have an index page that lists all users. This has the following in the Users controller -
public ViewResult Index()
{
return View(userRepository.AllIncluding(user => user.Roles));
}
and then the view starts with
@model IEnumerable<TRS.Models.User>
and then uses
@foreach (var item in Model) {
to loop through all users in my model.
I now need to change my model to a ViewModel that contains both the User model and an extended UserDetails model.
I have changed my Index view to use the view model -
@model IEnumerable<TRS.ViewModels.RegisterViewModel>
But I don't know how I should be going about filling the ViewModel in my controller -
public ViewResult Index()
{
var viewModel = new RegisterViewModel
{
UserName = "???"
FirstName = "???"
LastName = "???"
};
return View(viewModel);
}
I assume I need to create an instance of the view model and then pass it to the view. But I don't understand how I can get data against each individual item. I'll obviously need to get all data for all users here and then loop through them in my view. Any ideas what I should be going in the controller above? What should replace the "???" with that will fill the viewModel with all the data? Or is this the wrong approach?
Thanks
Edit - Models added -
public class User
{
[Key]
public string UserName { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual UserDetails UserDetails { get; set; }
}
public class UserDetails
{
[Key]
public string UserName { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
[Required]
public virtual User User { get; set; }
}
Edit - From View -
<td>
@foreach (Role role in item.Roles){
@role.RoleName <br />
}</td>
Upvotes: 0
Views: 157
Reputation: 1039060
public ActionResult Index()
{
var usersVm = userRepository
.AllIncluding(user => user.Roles)
.Select(user => new RegisterViewModel
{
UserName = user.UserName
FirstName = user.UserDetails.FirstName
LastName = user.UserDetails.LastName
});
return View(usersVm);
}
Upvotes: 1
Reputation: 564
it is unclear from your question what UserDetails look like.
You should not use IEnumerable<RegisterViewModel> in your view. The RegisterViewModel should be the container of everything you will need in the view:
public ViewResult Index()
{
var usersDetails = GetUserDetails(userRepository.AllIncluding(user => user.Roles));
var viewModel = new RegisterViewModel
{
UserDetails = usersDetails.ToList(),
SomeMoreDataRequiredByTheView= "1"
};
return View(viewModel);
}
//you can use automapper to do this dirty job.
private IEnumerable<UserDetails> GetUserDetails(IEnumerable<User> users)
{
foreach(var user in users)
{
yield return new UserDetails()
{
FullName = user.FirstName + " " + user.LastName,
// Other stuff you want
};
}
}
Upvotes: 0
Reputation: 1035
Your viewModel
Public Class RegisterViewModel
{
Public IEnumerable<TRS.Models.User> AllUsers {get;set;}
Public IEnumerable<TRS.Models.UserDetails> UserDetails {get;set;}
}
Then in your controller
public ViewResult Index()
{
var viewModel = new RegisterViewModel
{
AllUsers = userRepository.AllIncluding(user => user.Roles).ToList()
};
var DetailList = new list<TRS.Models.UserDetails>();
foreach(var user in viewModel.AllUsers)
{
DetailList.add(new userDetails
{
name = user.Name,
age = user.age,
....
}
}
viewModel.UserDetails = DetailList;
return View(viewModel);
}
Upvotes: 0
Reputation: 20674
Automapper was created for this very thing. I'd highly recommend it.
Take a read of getting started section of wiki.
Once you have it configured your controller code would look something like this:
List<RegisterViewModel> registrants =
Mapper.Map<List<User>, List<RegisterViewModel>>(users);
Though you might want to consider a viewmodel that has a list of registrants on them but that is up to you.
Upvotes: 0