Reputation: 245
Im trying to populate my Html.Listbox with all the users of my ASP.NET user database.
I have created a ViewModel that looks like this:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Web.Mvc;
using System.Web.Security;
namespace SkyLearn.Areas.Users.Models
{
public class UsersViewModel
{
MembershipUserCollection membershipuserscollection { get; set; }
public List<MembershipUser> membershipuserslist { get; set; }
public List<SelectListItem> AvailableUsers { get; set; }
public UsersViewModel()
{
availableUsers = new List<SelectListItem>();
}
}
}
And a Actionresult that looks like this:
public ActionResult Index()
{
var users = Membership.GetAllUsers().Cast<MembershipUser>();
UsersViewModel model = new UsersViewModel();
foreach (MembershipUser user in users)
{
SelectListItem selectuser = new SelectListItem();
selectuser.Text = user.UserName;
selectuser.Value = user.UserName;
model.AvailableUsers.Add(selectuser);
}
return View(model);
}
On my view i try to populate the list like this:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SkyLearn.Areas.Users.Models.UsersViewModel>" %>
<%= Html.ListBox("AvailableUsers", Model.AvailableUsers)%>
When i run the code i get the follow error:
CS1579: foreach statement cannot operate on variables of type 'SkyLearn.Areas.Users.Models.UsersViewModel' because 'SkyLearn.Areas.Users.Models.UsersViewModel' does not contain a public definition for 'GetEnumerator'
Upvotes: 0
Views: 1976
Reputation: 1038930
The problem is that you are using the same name as the first argument of the ListBox helper as a property on your view model (AvailableUsers
). That's not correct. The first argument should represent a property on your view model that will be used to bind the selected values back. In the case of a ListBox helper, this should be a collection because the user can select multiple values. In the case of a DropDownList helper this should be a simple scalar property. The second argument (in both cases) represents a collection of SelectListItem
which will be used to render the available options.
So let's take an example of how you could improve your view model:
public class UsersViewModel
{
public string[] SelectedUsers { get; set; }
public IEnumerable<SelectListItem> AvailableUsers { get; set; }
}
and then the controller:
public ActionResult Index()
{
var users = Membership.GetAllUsers().Cast<MembershipUser>();
var model = new UsersViewModel
{
AvailableUsers = users.Select(x => new SelectListItem
{
Value = x.UserName,
Text = x.UserName
})
};
return View(model);
}
and finally the view:
<%@ Page
Title=""
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<UsersViewModel>"
%>
<%= Html.ListBoxFor(x => x.SelectedUsers, Model.AvailableUsers) %>
You will notice that I have gotten rid of the membershipuserscollection
and the membershipuserslist
properties that you had initially in your view model which accomplish no purpose in this example. The first one is private and the second one is a collection of a domain model (MembershipUser
) so it has absolutely no place in a view model.
Upvotes: 0
Reputation: 60503
AvailableUsers is not initialized, you can do this in the constructor of your ViewModel, for example.
public class UsersViewModel
{
public UsersViewModel {
AvailableUsers = new List<SelectListItem>();
}
MembershipUserCollection membershipuserscollection { get; set; }
public List<MembershipUser> membershipuserslist { get; set; }
public List<SelectListItem> AvailableUsers { get; private set; }
}
Upvotes: 1