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

ru-RU | created at: 10/5/2011 | published: 10/5/2011 | updated at: 1/1/2018 | number of views: 8538

Не так давно передо мной была поставлена задача реализовать в проекте 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, которые вы хотите пользовать на страницах сайта.

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

2

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

Comments (8)

12/5/2011 9:24:00 AM Мурадов Артем
Собственно, а о чем пост? Вы поставили задачу и предлагаете читателям качать проект и самим разбираться с решением?
12/5/2011 9:27:00 AM Calabonga

Статья описывает как и с помощью чего можно сделать каскадное обновление выпадающих списков. А если не понятно, или что-то не получается, то можно скачать пример и посмотреть как это работает.

12/5/2011 11:44:00 AM Мурадов Артем

по поводу "с помощью чего" я ещё соглашусь, но вот "как" при помощи DropDownListFor сделать зависимые выпадающие списки тут ни слова.
Поясню:
1. Заголовок "Задача" - тут поставновка задачи, то есть что вообще нужно получить в итоге
2. Заголовки "О чем речь", "Концепция" и "Тонкости и необходимые условия" описывают составляющие
- Бизнес-объекты
- Интерфейс (в виде картинки) того, что мы хотим получить
- 2 метода какого то контроллера, которые возвращают какие то данные (то, что это данные для выкидушек, я уже сам догадался, так как в тексте об этом вообще ничего не сказано)
А вот как эти инструменты собрать вместе, да ещё и валидацию прикрутить, из этого текста мне совершенно не ясно.
А ещё:
"Тут важно заметить, что количество сущностей, которое должно быть возвращено на какой-либо форме, должно быть соответствовать тем методам в контроллере с пометкой JsonResult, которые вы хотите пользовать на страницах сайта." - я в этом абзаце даже смысла не увидел. Серьёзно - читал раз 10, и не понял, о чем речь вообще.
К тому же у вас в заголовке написано "ASP.NET MVC 3: Каскадные зависимости в MVC 3 или зависимый DropDownListFor" - и это единственное упоминание DropDownListFor во всем посте.

P.S. Я врзможно просто придираюсь, и у меня нет оснований сомневаться в Вашем профессионализме, но данный пост мне кажется абсолютно бессмысленным. Как первый из серии постов, в котором нужно поставить задачу - вполне подойдет, а как отдельный полноценный пост - ну никак не подходит.

12/5/2011 1:08:00 PM Calabonga

Спасибо за комментарии, уважаемые.
Должен признать, что статья писалась, что называется, "на скорую руку" и подлежит, как минимум, основательной переработке, но в силу того, что со временем сейчас напряженка, сделаю это чуть позже. Спасибо за понимание.

11/14/2014 1:27:36 PM Олег

Здравствуйте. Понадобилось реализовать каскадные дропдаунлисты на ASP.NET MVC. Нашел Вашу статью. Скачав код столкнулся с отсутствием sql базы и соответственно с невозможностью запустить проект и разобраться как же оно таки работает. Ясно, что статья написана 3 года назад..... Но вдруг Вы все таки можете помочь ...

11/14/2014 2:44:37 PM Calabonga

Олег, я посмотрю что можно сделать. На выходных постараюсь найти время.

11/16/2014 3:35:47 PM Олег

Большое спасибо! Вопрос все еще актуален для меня)

11/17/2014 11:43:06 AM Calabonga

Олег, как я предполагал, никаких баз данных я не нашел, так что извините, ничем не могу помочь. Но, честно сказать, база данных там и не нужна для понимания принципов. Данные можно брать откуда угодно. Сам принцип получение данных и обновления не поменялся. Если потребуется помощь - пишите через форму обратной связи с указанием способа связи, например, скайп. Попробую помочь чем смогу :)