So, I am implementing ASP Membership and Role management in my application. I also have a second User table with all non-membership related information. I set the E-mail as the username in Membership and as the foreign key in my User table.
I am customizing the registration page to include a dropdown so a manager can be selected when the account is created. The list of managers is generated by finding all Membership users with the role “Manager” then creating a collection of Users where the foreign keys match the results.
List<string> managerNames = new List<string>(Roles.GetUsersInRole("Manager"));
var managers = from m in _db.Users where managerNames.Contains(m.Email) select m;
ViewBag.managers = managers;
Now I have to use that collection of users to populate a dropdown in my view that has the Name attribute set to “ManagerID” (to match my RegistrationModel), the value of each option set to the primary key of the User, and the displayed text in the dropdown showing the DisplayName of the User model.
I can go through the tedious task of looping through my “managers” collection and populating a separate SelectListItem, then passing the SelectListItem into a @Html.DropDown("ManagerID", newSelectListItem), but that seems excessive. Is there a more direct (or acceptable) way to do this?
EDIT
I added this to my controller
var selectList = new List<SelectListItem>();
foreach (var manager in managers)
{
selectList.Add(new SelectListItem(){
Value = manager.UserID.ToString(),
Text = manager.DisplayName,
Selected = false
});
}
ViewBag.managers = selectList;
and this to my view
@Html.DropDownList("ManagerID", (List<SelectListItem>)ViewBag.managers)
and it works. Is this still the best approach?
No. The best approach is to use view models and forget about the existence of ViewBag/ViewData. So start by designing a view model which will meet the requirements of your view (display a ddl of managers):
and then have your controller action populate this view model and pass it to the view:
and finally in your strongly typed view:
So everytime you employ ViewBag/ViewData in an ASP.NET MVC applications an alarm should ring telling you that there is a better way.