title: ASP.NET MVC Core Cascading DropDownList
body: <p>I'm having trouble finding a tutorial / video that shows how to implement Cascading DropDownList from a Database using EntityFramework. I'm using ASP.NET MVC Core, EntityFramework Core with C#.</p>
  
  <p>As of now, I'm able to retrieve the data from my database to my 3 DropDownList fine.</p>
  
  <p>What I would like to be able to accomplish is to have the user select a State first which would then display all Cities related to that State. Then after user has selected a City it would display the Zip Code(s) related to the City.</p>
  
  <p>Any help would be greatly appreciated. </p>
  
  <p><strong>Models</strong></p>
  
  <pre><code>    public class Customer
  {
      public int CustomerId { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
  
      public int StateId { get; set; }
      public int CityId { get; set; }
      public int ZipId { get; set; }
  
      public State State { get; set; }
      public City City { get; set; }
      public Zip Zip { get; set; }
  }
  
      public class State
  {
      public int StateId { get; set; }
      public string Abbr { get; set; }
  
      public List&lt;Customer&gt; Customers { get; set; }
  }
  
      public class City
  {
      public int CityId { get; set; }
      public string Name { get; set; }
  
      public int StateId { get; set; }
      public State State { get; set; }
  
      public List&lt;Customer&gt; Customers { get; set; }
  }
  
      public class Zip
  {
      public int ZipId { get; set; }
      public string PostalCode { get; set; }
  
      public int CityId { get; set; }
      public City City { get; set; }
  
      public List&lt;Customer&gt; Customers { get; set; }
  }
  </code></pre>
  
  <p><strong>ViewModels</strong></p>
  
  <pre><code>    public class CustomerFormVM
  {
      public int CustomerId { get; set; }
  
      [Display(Name = "First Name")]
      [StringLength(50)]
      public string FirstName { get; set; }
  
      [Display(Name = "Last Name")]
      [StringLength(50)]
      public string LastName { get; set; }
  
      [Required(ErrorMessage = "Select State")]
      [Display(Name = "State")]
      public int StateId { get; set; }
  
      //public IEnumerable&lt;State&gt; States { get; set; }
      public IEnumerable&lt;SelectListItem&gt; States { get; set; }
  
      [Required(ErrorMessage = "Select City")]
      [Display(Name = "City")]
      public int CityId { get; set; }
  
      //public IEnumerable&lt;City&gt; Citys { get; set; }
      public IEnumerable&lt;SelectListItem&gt; Citys { get; set; }
  
      [Required(ErrorMessage = "Select Zip")]
      [Display(Name = "Zip")]
      public int ZipId { get; set; }
  
      //public IEnumerable&lt;Zip&gt; Zips { get; set; }
      public IEnumerable&lt;SelectListItem&gt; Zips { get; set; }
  }
  </code></pre>
  
  <p><strong>CustomerController</strong></p>
  
  <pre><code>public class CustomerController : Controller
  {
      private MultiDbContext db;
  
      public CustomerController(MultiDbContext context)
      {
          db = context;
      }
  
      // GET: /&lt;controller&gt;/
      public IActionResult Index()
      {
          return View(db.Customers.ToList());
      }
  
      public IActionResult getCititesFromDatabaseByStateId(int id)
      {
          return View(db.Citys.Where(c =&gt; c.StateId == id).ToList());
      }
  
      public IActionResult getCities(int id)
      {
          var cities = new List&lt;City&gt;();
          cities = getCititesFromDatabaseByStateId(id); //call repository
          return Json(cities);
      }
  
      public ActionResult Create()
      {
          var states = db.States.ToList();
          var citys = db.Citys.ToList();
          var zips = db.Zips.ToList();
  
          var viewModel = new CustomerFormVM
          {
              States = states,
              Citys = citys,
              Zips = zips
          };
  
          return View(viewModel);
      }
  
  
      [HttpPost]
      [ValidateAntiForgeryToken]
      public ActionResult Create(CustomerFormVM vm)
      {
          if (ModelState.IsValid)
          {
              var customer = new Customer();
              {
                  customer.FirstName = vm.FirstName;
                  customer.LastName = vm.LastName;
                  customer.StateId = vm.StateId;
                  customer.CityId = vm.CityId;
                  customer.ZipId = vm.ZipId;
              }
              db.Customers.Add(customer);
              db.SaveChanges();
              return RedirectToAction("Index");
          }
  
          else
          {
              vm.States = db.States.ToList();
              vm.Citys = db.Citys.ToList();
              vm.Zips = db.Zips.ToList();
              return View(vm);
          }
      }
  
  
      public ActionResult Edit(int? id)
      {
          if (id == null)
          {
              return NotFound();
          }
  
          var customervm = new CustomerFormVM();
          {
              Customer customer = db.Customers.SingleOrDefault(c =&gt; c.CustomerId == id);
  
              if (customer == null)
              {
                  return NotFound();
              }
  
              customervm.CustomerId = customer.CustomerId;
              customervm.FirstName = customer.FirstName;
              customervm.LastName = customer.LastName;
  
              // Retrieve list of States
              var states = db.States.ToList();
              customervm.States = states;
  
              // Retrieve list of Citys
              var citys = db.Citys.ToList();
              customervm.Citys = citys;
  
              // Retrieve list of Citys
              var zips = db.Zips.ToList();
              customervm.Zips = zips;
  
              // Set the selected state
              customervm.StateId = customer.StateId;
  
              // Set the selected city
              customervm.CityId = customer.CityId;
  
              // Set the selected zip
              customervm.ZipId = customer.ZipId;
          }
          return View(customervm);
      }
  
  
      [HttpPost]
      [ValidateAntiForgeryToken]
      public ActionResult Edit(CustomerFormVM vmEdit)
      {
          if (ModelState.IsValid)
          {
              Customer customer = db.Customers.SingleOrDefault(c =&gt; c.CustomerId == vmEdit.CustomerId);
  
              if (customer == null)
              {
                  return NotFound();
              }
  
              customer.FirstName = vmEdit.FirstName;
              customer.LastName = vmEdit.LastName;
              customer.StateId = vmEdit.StateId;
              customer.CityId = vmEdit.CityId;
              customer.ZipId = vmEdit.ZipId;
  
              db.Entry(customer).State = EntityState.Modified;
              db.SaveChanges();
              return RedirectToAction("Index");
          }
          return View(vmEdit);
      }
  }
  </code></pre>
  
  <p><strong>Create View</strong></p>
  
  <pre><code>        &lt;div class="form-group"&gt;
          @Html.LabelFor(c =&gt; c.FirstName)
          @Html.TextBoxFor(c =&gt; c.FirstName, new { @class = "form-control" })
      &lt;/div&gt;
  
      &lt;div class="form-group"&gt;
          @Html.LabelFor(c =&gt; c.LastName)
          @Html.TextBoxFor(c =&gt; c.LastName, new { @class = "form-control" })
      &lt;/div&gt;
  
      &lt;div class="form-group"&gt;
          @*@Html.LabelFor(s =&gt; s.StateId)
              @Html.DropDownListFor(s =&gt; s.StateId, new SelectList(Model.States, "StateId", "Abbr"), "", new { @class = "form-control" })
              @Html.ValidationMessageFor(s =&gt; s.StateId)*@
  
          &lt;label asp-for="StateId "&gt;&lt;/label&gt;
          &lt;select asp-for="StateId " asp-items="Model.States" class="form-control" id="state-target"&gt;&lt;/select&gt;
          &lt;span asp-validation-for="StateId " class="text-danger"&gt;&lt;/span&gt;
      &lt;/div&gt;
  
      &lt;div class="form-group"&gt;
          @*@Html.LabelFor(ct =&gt; ct.CityId)
              @Html.DropDownListFor(ct =&gt; ct.CityId, new SelectList(Model.Citys, "CityId", "Name"), "", new { @class = "form-control" })
              @Html.ValidationMessageFor(ct =&gt; ct.CityId)*@
  
          &lt;label asp-for="CityId"&gt;&lt;/label&gt;
          &lt;select asp-for="CityId" asp-items="Model.Citys" class="form-control" id="city-target"&gt;&lt;/select&gt;
          &lt;span asp-validation-for="CityId" class="text-danger"&gt;&lt;/span&gt;
      &lt;/div&gt;
  
      &lt;div class="form-group"&gt;
          @Html.LabelFor(z =&gt; z.ZipId)
          @Html.DropDownListFor(z =&gt; z.ZipId, new SelectList(Model.Zips, "ZipId", "PostalCode"), "", new { @class = "form-control" })
          @Html.ValidationMessageFor(z =&gt; z.ZipId)
      &lt;/div&gt;
  
      &lt;div class="form-group"&gt;
          &lt;button type="submit" class="btn btn-primary"&gt;Submit&lt;/button&gt;
      &lt;/div&gt;
  }
  
  @section scripts {
      &lt;script src="~/lib/jquery-validation/dist/jquery.validate.js"&gt;&lt;/script&gt;
      &lt;script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"&gt;&lt;/script&gt;
      &lt;script src="~/lib/js/example.js"&gt;&lt;/script&gt;,
  }
  </code></pre>