ASP.NET MVC: Каскадные зависимости в MVC 3 или зависимый DropDownListFor

Опубликовано 06.10.2011 03:17:57 в категории Микросервисы

Не так давно передо мной была поставлена задача реализовать в проекте ASP.NET MVC 3 некое подобие выпадающих списков (ComboBox или DropDownList) зависимых один от другого. Это значит, что данные обновляются в зависимости от другого Html-объекта. Задача была поставлена и решена.

Задача

Требуется реализовать обновление одного html-контрола в зависимости от выбранных данных в другом html-контроле. Что-то подобное уже было описано в статье для Silverlight, теперь настало время для ASP.NET MVC3.

О чем речь

Есть некоторое количество зависимых классов. Первый называется “город” (City):

public class City
{
 public int Id { get; set; }

 [StringLength(50), Required]
 public string Name { get; set; }
}  

Также можно допустить, что есть зависимый от города “район” (Disctrict):

public class District
{
    public int Id { get; set; }

    [StringLength(50), Required]
    public string Name { get; set; }

    public virtual City City { get; set; }

    [ForeignKey("City"), Required]
    public int CityId { get; set; }
}

А еще есть микрорайон (subdistrict), который теперь уже зависит от района:

public class Subdistrict
{
    public int Id { get; set; }

    [StringLength(50), Required]
    public string Name { get; set; }

    public virtual District District { get; set; }

    [ForeignKey("District"), Required]
    public int DistrictId { get; set; }
}

Наверное вы уже догадались, что мы будем работать с неким подобием адреса, а если говорить точнее, то мы будем создавать новый экземпляр типа адрес, в котором есть неотъемлемые части, такие как “Город”, “Район”, “Микрорайон”…. Для нашего примера этого достаточно.

Концепция

Есть три зависимые сущности, которые должны “правильно” отображать на странице ASP.NET MVC 3 сайта. При выборе города должен обновляться список районов, при смене района должен обновляться список микрорайонов.

Тонкости и необходимые условия

Для того чтобы всё заработало так как требуется – надо сделать в контроллере (Controller) два метода:

public JsonResult LoadDistricts(int id)
{
   List<District> result = new List<District>();
   var tmp = districtRepository.All.Where(x => x.CityId == id);
   tmp.ToList().ForEach(x => result.Add(new District { Id = x.Id, Name = x.Name }));
   return Json(result, JsonRequestBehavior.AllowGet);
}

и еще один:

public JsonResult LoadSubDistricts(int id)
{
   List<Subdistrict> result = new List<Subdistrict>();
   var tmp = subdistrictRepository.All.Where(x => x.DistrictId == id);
   tmp.ToList().ForEach(x => result.Add(new Subdistrict { Id = x.Id, Name = x.Name }));

   return Json(result, JsonRequestBehavior.AllowGet);
}

Тут важно заметить, что количество сущностей, которое должно быть возвращено на какой-либо форме, должно быть соответствовать тем методам в контроллере с пометкой JsonResult, которые вы хотите пользовать на страницах сайта.

Ключевое слово при добавлении нового объекта в базу данных – это валидация. Существует несколько видов – “серверная”, “клиентская”, я сейчас про “клиентскую”, еще ее называют, “валидация ввода”.

Итак, друзья мои, и недруги, будут вопросы – пишите в комментарии.

Комментарии к статье ()

Загрузка...

Что-то пошло не по сценарию и завершилось ошибкой. Перезагрузить страницу (F5) 🗙

Переподключаем сервер...

Переподключение сломалось... Пробуем еще раз сек.

Не получилось переподключится.
Пожалуйста, обновите страницу F5

Сессия была поставлена сервером на паузу.

Восстановить сессию не получилось.
Пожалуйста, обновите страницу F5.