development
I have a model:
public class DbUserRole { public int UserRoleId { get; set; } public string UserRole { get; set; } } public class DbUserRoles { public List<DbUserRole> GetRoles() { BugnetReports RoleDropDown = new BugnetReports(); List<DbUserRole> Roles = new List<DbUserRole>(); DataSet table = RoleDropDown.userRoleDropDown(); foreach (DataRow item in table.Tables[0].Rows) { DbUserRole ur = new DbUserRole(); ur.UserRole = Convert.ToString(item["UserRoleName"]); ur.UserRoleId = Convert.ToInt32(item["UserRoleID"]); Roles.Add(ur); } return Roles; } }
And here is the Controller that loads the view:
// // GET: /Admin/AddNewUser public ActionResult AddNewUser() { DbUserRoles Roles = new DbUserRoles(); return View(Roles.GetRoles()); }
I can get the items in the list to display using a @foreach loop as shown below:
@foreach
@foreach (var item in Model) { <tr> <td> @item.UserRoleId </td> <td> @item.UserRole </td> </tr> }
But how do I populate a dropdownlist with the model that is passed through, I have tried
@Html.DropDownListFor(x => x.UserRole)
but I'm having no luck.
You can separate out your business logic into a viewmodel, so your view has cleaner separation.
First create a viewmodel to store the Id the user will select along with a list of items that will appear in the DropDown.
DropDown
ViewModel:
public class UserRoleViewModel { // Display Attribute will appear in the Html.LabelFor [Display(Name = "User Role")] public int SelectedUserRoleId { get; set; } public IEnumerable<SelectListItem> UserRoles { get; set; } }
References:
DisplayAttribute
Inside the controller create a method to get your UserRole list and transform it into the form that will be presented in the view.
UserRole
Controller:
private IEnumerable<SelectListItem> GetRoles() { var dbUserRoles = new DbUserRoles(); var roles = dbUserRoles .GetRoles() .Select(x => new SelectListItem { Value = x.UserRoleId.ToString(), Text = x.UserRole }); return new SelectList(roles, "Value", "Text"); } public ActionResult AddNewUser() { var model = new UserRoleViewModel { UserRoles = GetRoles() }; return View(model); }
SelectListItem
SelectList Constructor (IEnumerable, String, String)
Now that the viewmodel is created the presentation logic is simplified
View:
@model UserRoleViewModel @Html.LabelFor(m => m.SelectedUserRoleId) @Html.DropDownListFor(m => m.SelectedUserRoleId, Model.UserRoles)
LabelExtensions.LabelFor
SelectExtensions.DropDownListFor
This will produce:
<label for="SelectedUserRoleId">User Role</label> <select id="SelectedUserRoleId" name="SelectedUserRoleId"> <option value="1">First Role</option> <option value="2">Second Role</option> <option value="3">Etc...</option> </select>
@Html.DropDownList("ddl",Model.Select(item => new SelectListItem { Value = item.RecordID.ToString(), Text = item.Name.ToString(), Selected = "select" == item.RecordID.ToString() }))
One way might be;
<select name="listbox" id="listbox"> @foreach (var item in Model) { <option value="@item.UserRoleId"> @item.UserRole </option> } </select>
Something close to:
@Html.DropDownListFor(m => m.UserRole, new SelectList(Model.Roles, "UserRoleId", "UserRole", Model.Roles.First().UserRoleId), new { /* any html attributes here */ })
You need a SelectList to populate the DropDownListFor. For any HTML attributes you need, you can add:
new { @class = "DropDown", @id = "dropdownUserRole" }
Instead of a List<UserRole>, you can let your Model contain a SelectList<UserRole>. Also add a property SelectedUserRoleId to store... well... the selected UserRole's Id value.
List<UserRole>
SelectList<UserRole>
SelectedUserRoleId
Fill up the SelectList, then in your View use:
@Html.DropDownListFor(x => x.SelectedUserRoleId, x.UserRole)
and you should be fine.
See also http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist(v=vs.108).aspx.
Your call to DropDownListFor needs a few more parameters to flesh it out. You need a SelectList as in the following SO question:
DropDownListFor
MVC3 DropDownListFor - a simple example?
With what you have there, you've only told it where to store the data, not where to load the list from.
@{ List<CategoryModel> CategoryList = CategoryModel.GetCategoryList(UserID); IEnumerable<SelectListItem> CategorySelectList = CategoryList.Select(x => new SelectListItem() { Text = x.CategoryName.Trim(), Value = x.CategoryID.Trim() }); } <tr> <td> <B>Assigned Category:</B> </td> <td> @Html.DropDownList("CategoryList", CategorySelectList, "Select a Category (Optional)") </td> </tr>
I'm going to approach this as if you have a Users model:
Users.cs
public class Users { [Key] public int UserId { get; set; } [Required] public string UserName { get; set; } public int RoleId { get; set; } [ForeignKey("RoleId")] public virtual DbUserRoles DbUserRoles { get; set; } }
and a DbUserRoles model that represented a table by that name in the database:
DbUserRoles.cs
public partial class DbUserRoles { [Key] public int UserRoleId { get; set; } [Required] [StringLength(30)] public string UserRole { get; set; } }
Once you had that cleaned up, you should just be able to create and fill a collection of UserRoles, like this, in your Controller:
var userRoleList = GetUserRolesList(); ViewData["userRoles"] = userRolesList;
and have these supporting functions:
private static SelectListItem[] _UserRolesList; /// <summary> /// Returns a static category list that is cached /// </summary> /// <returns></returns> public SelectListItem[] GetUserRolesList() { if (_UserRolesList == null) { var userRoles = repository.GetAllUserRoles().Select(a => new SelectListItem() { Text = a.UserRole, Value = a.UserRoleId.ToString() }).ToList(); userRoles.Insert(0, new SelectListItem() { Value = "0", Text = "-- Please select your user role --" }); _UserRolesList = userRoles.ToArray(); } // Have to create new instances via projection // to avoid ModelBinding updates to affect this // globally return _UserRolesList .Select(d => new SelectListItem() { Value = d.Value, Text = d.Text }) .ToArray(); }
Repository.cs
My Repository function GetAllUserRoles() for the function, above:
GetAllUserRoles()
public class Repository { Model1 db = new Model1(); // Entity Framework context // User Roles public IList<DbUserRoles> GetAllUserRoles() { return db.DbUserRoles.OrderBy(e => e.UserRoleId).ToList(); } }
AddNewUser.cshtml
Then do this in your View:
<table> <tr> <td> @Html.EditorFor(model => model.UserName, htmlAttributes: new { @class = "form-control" } ) </td> <td> @Html.DropDownListFor(model => model.RoleId, new SelectList( (IEnumerable<SelectListItem>)ViewData["userRoles"], "Value", "Text", model.RoleId), htmlAttributes: new { @class = "form-control" } ) </td> </tr> </table>
@model AdventureWork.CRUD.WebApp4.Models.EmployeeViewModel @{ ViewBag.Title = "Detalle"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Ingresar Usuario</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.Employee.PersonType, labelText: "Tipo de Persona", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownListFor(model => model.Employee.PersonType, new List<SelectListItem> { new SelectListItem{ Text= "SC", Value = "SC" }, new SelectListItem{ Text= "VC", Value = "VC" }, new SelectListItem{ Text= "IN", Value = "IN" }, new SelectListItem{ Text= "EM", Value = "EM" }, new SelectListItem{ Text= "SP", Value = "SP" }, }, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Employee.PersonType, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.EmployeeGender, labelText: "Genero", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownListFor(model => model.Employee.EmployeeGender, new List<SelectListItem> { new SelectListItem{ Text= "Masculino", Value = "M" }, new SelectListItem{ Text= "Femenino", Value = "F" } }, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Employee.EmployeeGender, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.PersonTitle, labelText: "Titulo", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.PersonTitle, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.PersonTitle, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.PersonFirstName, labelText: "Primer Nombre", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.PersonFirstName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.PersonFirstName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.PersonMiddleName, labelText: "Segundo Nombre", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.PersonMiddleName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.PersonMiddleName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.PersonLastName, labelText: "Apellido", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.PersonLastName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.PersonLastName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.PersonSuffix, labelText: "Sufijo", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.PersonSuffix, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.PersonSuffix, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.DepartmentID, labelText: "Departamento", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownListFor(model => model.Employee.DepartmentID, new SelectList(Model.ListDepartment, "DepartmentID", "DepartmentName"), htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Employee.DepartmentID, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.EmployeeMaritalStatus, labelText: "Estado Civil", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownListFor(model => model.Employee.EmployeeMaritalStatus, new List<SelectListItem> { new SelectListItem{ Text= "Soltero", Value = "S" }, new SelectListItem{ Text= "Casado", Value = "M" } }, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Employee.EmployeeMaritalStatus, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.ShiftId, labelText: "Turno", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownListFor(model => model.Employee.ShiftId, new SelectList(Model.ListShift, "ShiftId", "ShiftName"), htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Employee.ShiftId, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.EmployeeLoginId, labelText: "Login", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.EmployeeLoginId, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.EmployeeLoginId, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.EmployeeNationalIDNumber, labelText: "Identificacion Nacional", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.EmployeeNationalIDNumber, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.EmployeeNationalIDNumber, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.EmployeeJobTitle, labelText: "Cargo", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.EmployeeJobTitle, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.EmployeeJobTitle, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.EmployeeBirthDate, labelText: "Fecha Nacimiento", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.EmployeeBirthDate, new { htmlAttributes = new { @class = "form-control datepicker" } }) @Html.ValidationMessageFor(model => model.Employee.EmployeeBirthDate, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Employee.EmployeeSalariedFlag, labelText: "Asalariado", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Employee.EmployeeSalariedFlag, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Employee.EmployeeSalariedFlag, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Guardar" class="btn btn-default" /> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10" style="color:green"> @ViewBag.Message </div> <div class="col-md-offset-2 col-md-10" style="color:red"> @ViewBag.ErrorMessage </div> </div> </div> }
참고URL : https://stackoverflow.com/questions/18382311/populating-a-razor-dropdownlist-from-a-listobject-in-mvc