Как лучше всего привязать @ Html.DropDownListFor в ASP.NET MVC5?

Я хочу связать @Html.DropDownListFor из Model данных без использования Viewbag и посмотреть множество различных примеров в Интернете. Но большинство из них используют Viewbag или метод расширения, и мне нужен лучший подход для решения этой проблемы. Я пробовал следующие методы, но, похоже, они не работают:

@Html.DropDownListFor(m => m.LabId, new SelectList(Model.Lab, "Id", "Name"), 
    "---- Select----", new { @class = "selectpicker" } )

Можно ли привязать @Html.DropDownListFor непосредственно из модели без использования Viewbag или какого-либо дополнительного метода в Controller в ASP.NET MVC5? Не могли бы вы привести несколько примеров, чтобы добиться наилучшего результата?


person Jack    schedule 17.09.2016    source источник
comment
ViewBag - это просто контейнер - передавайте все необходимые данные в виде строго типизированного @model   -  person Jasen    schedule 17.09.2016


Ответы (2)


Строго типизированная модель представления, не использующая динамические элементы, такие как ViewBag

Вы можете добавить новое свойство в свою модель представления для опций SELECT типа IEnumrable<SelectListItem>.

модель представления - это простой класс POCO, используемый для передачи данных между методом представления и действия и наоборот. Они специфичны для представлений. Добавьте свойства, необходимые только для представления.

public class CreateUserVm
{
   public IEnumrable<SelectListItem> Labs { set;get;}
   public int SelectedLabId { set;get;}
   //Add other properties as needed for the view
}

и в вашем действии GET создайте объект этой модели представления, загрузите свойство Labs и отправьте его в представление.

public ActionResult Create()
{
  var vm= new CreateUserVm();
  // Hard coded for demo. You can replace with real data from db
  vm.Labs = new List<SelectListItem> {
     new SelectListItem { Value="1", Text="One" },
     new SelectListItem { Value ="2", Text="Two" }
  };
  return View(vm);
}

и в представлении, которое строго типизировано для этой модели представления, вызовите вспомогательный метод DropDownListFor

@model CreateUserVm
@Html.DropDownListFor(f=>f.SelectedLabId, Model.Labs,"Select one")

Предварительный выбор варианта в раскрывающемся списке

Если вы хотите предварительно выбрать один вариант, когда razor отображает страницу, вы можете установить для свойства SelectedLabId вашей модели представления значение свойства value элемента Option (SelectListItem).

public ActionResult Create()
{
  var vm= new CreateUserVm();
  // Hard coded for demo. You can replace with real data from db
  vm.Labs = new List<SelectListItem> {
     new SelectListItem { Value="1", Text="SugarLab" },
     new SelectListItem { Value ="2", Text="CandyLab" },
     new SelectListItem { Value ="3", Text="SodaLab" }
  };
  vm.SelectedLabId = 2; // Will set "CandyLab" option as selected
  return View(vm);
}

Если вы хотите использовать реальные данные вместо жестко закодированных двух элементов, вы можете сделать это

vm.Labs = dbContext.Labs.Select(x=>new SelectListItem { Value=x.Id.ToString(),
                                                        Text= x.Name }).ToList();

Предположим, что dbContext - это ваш объект класса DbContext и у него есть свойство Labs типа DbSet<Lab>, где каждая сущность Lab имеет свойство Id и Name.

person Shyju    schedule 17.09.2016
comment
Большое спасибо за подробные объяснения и ответ. Я думаю, что это самый чистый способ заполнения раскрывающегося списка. - person Jack; 18.09.2016
comment
Когда дело доходит до DropDownListFor, существует тонкое различие между значением по умолчанию и выбранным значением, и я бы сказал, что ваш метод предварительного выбора значения не совсем правильный - вам лучше использовать для этого один из параметров DropDownListFor, а не устанавливать его на модель. Я написал короткую статью именно по этой проблеме - nimblegecko.com/ - person Art; 28.09.2016

Вы идете по правильному пути, имея элементы списка в своей модели. Я не знаю, как вы реализовали это в своем коде.

Свойство Lab в вашем классе модели должно быть IEnumerable, List или Collection того, что вы хотите. а затем на вашем бритвенном взгляде все выглядит нормально.

Возможно, вы забываете инициализировать список из метода действия в контроллере перед его отправкой в ​​представление. Например:

var model = new ViewModel{

Labs = repository.GetLabs();
}

Выше я предполагаю, что репозиторий должен быть чем-то, что имеет доступ или средства для получения необходимых данных, а также что свойство Labs определено как IEnumerable<Lab> Labs в классе ViewModel.

Все должно работать. Возможно, вам следует четко понимать, какую ошибку вы получаете.

person pmbanugo    schedule 17.09.2016