Mou
Mou

Reputation: 16312

ASP.Net MVC: How to bind dropdown with deep nested property

suppose below is my view model classes.

public class MainViewModel
{
    public List<Student> Students { get; set; }
    public int SelectedState = 0;

}

public class Student
{
    public int ID = 0;
    public string Name = "";
    public int StateID = 0;
    public List<States> States { get; set; }

}

public class States
{
    public int ID = 0;
    public string Name = "";
}

now how could i bind dropdown with nested property called States of student class ?

@Html.DropDownListFor(x => x.SelectedState new SelectList(Model.Students.States, "ID", "Name", Model.SelectedState), "-- Select States--", new { id = "cboState", @class = "edit-mode" })

this is not working SelectList(Model.Students.States, "ID", "Name", Model.SelectedState) how to refer this Model.Students.States

please discuss this issue with code sample. each student has relation with states.

Upvotes: 0

Views: 1263

Answers (1)

QuietNaN
QuietNaN

Reputation: 371

Check this out:

@Html.DropDownListFor(x => x.SelectedState, new SelectList(Model.Students.FirstOrDefault().States, "ID", "Name", Model.SelectedState), "-- Select States--", new { id = "cboState", @class = "edit-mode" })

But its better to save States List in ViewBag in your Controller:

ViewBag.States = (_context or _serviceLayer).(States or GetStates()).Select(s => new SelectListItem { Value = s.ID, Text = s.Name, Selected = s.ID == viewModel.SelectedState }).ToList();

And on View:

@Html.DropDownListFor(x => x.SelectedState, (List<SelectListItem>)ViewBag.States, "-- Select States--", new { id = "cboState", @class = "edit-mode" })

REQUESTED EDIT:

Models:

namespace MyProject.Models
{
    public class ViewInfo
    {
        public int StateID { get; set; }
    }

    public class Student
    {
        public int ID { get; set; }
        public string FullName { get; set; }
        public int StateID { get; set; }
    }
    public class State
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

Controllers:

using MyProject.Models;
namespace MyProject.Controllers
{
    public class StudentsController : Controller
    {
        private MyDBEntities _context;

        public StudentsController()
        {
            this._context = new MyDBEntities();
        }

        // StudentsController
        public ActionResult Index()
        {
            ViewBag.ViewInfo = new ViewInfo { StateID = 1 };
            ViewBag.StateID = _context.States.Select(s => new SelectListItem { Value = s.ID, Text = s.Name }).ToList();
            return View(_context.Students.ToList());
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(ViewInfo viewInfo)
        {
            ModelState.Clear();

            ViewBag.ViewInfo = viewInfo;
            ViewBag.StateID = _context.States.Select(s => new SelectListItem { Value = s.ID, Text = s.Name, Selected = s.ID == viewInfo.StateID }).ToList();
            return View(_context.Students.Where(s => s.StateID == viewInfo.StateID).ToList());
        }
    }
}

And the View:

@using MyProject.Models;
@model IEnumerable<MyProject.Models.Student>

@{
    ViewBag.Title = "Students";
    ViewInfo viewInfo = ViewBag.ViewInfo;
}

<div class="page-header">
    <h2>Students</h2>
</div>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken();

    @Html.DropDownList("StateID", null, new { @class = "form-control" })

    <input type="submit" value="Filter" class="btn btn-primary" />

    // Students Table
}

Upvotes: 1

Related Questions