Привязка выпадающего списка из базы данных

#c# #asp.net #asp.net-mvc #model-view-controller #asp.net-mvc-5

#c# #asp.net #asp.net-mvc #модель-представление-контроллер #asp.net-mvc-5

Вопрос:

Я создаю представление, в котором будут отображаться табличные данные на основе выбора из двух выпадающих списков, первый, в котором выбираются отделы, заполняется из базы данных. Второй — это статический выпадающий список для «Года», который я еще не получил. Есть ответы на похожие вопросы, но я просмотрел их и попробовал все. Я дошел до того, что получаю нулевое исключение в представлении, в котором я создал разметку для выпадающего списка.

Вид:

Departments возвращается как null. Я новичок в MVC и собрал это вместе из онлайн-примеров. Я предполагаю, что моя модель неверна.

 @model IEnumerable<BudgetDemo.Models.BudgetsActualsViewModel>

@foreach (var item in Model)
{
    @Html.DropDownListFor(m => item.Departments, 
        new SelectList(item.Departments.Select(x => x.Text)))
}
 

ViewModel:

 public class BudgetsActualsViewModel
{
    [Display(Name = "Cost Center/Department")]
    [Required(ErrorMessage = "Cost Center/Department is required.")]
    [StringLength(62)]
    public string SelectedDepartment { get; set; }
    public IEnumerable<SelectListItem> Departments { get; set; }
}
 

Контроллер:

 public ActionResult GetBudgetsActuals()   
{
    repo = new BudgetDemoRepository();
    ModelState.Clear();
    return View(repo.GetBudgetsActuals());
}
 

Класс репозитория:

 public List<BudgetsActualsViewModel> GetBudgetsActuals()  
{
    ...
    List<BudgetsActualsViewModel> budgetsActualsList = new List<BudgetsActualsViewModel>();
    // Query returning correct data from DB here

    for (int i = 0; i < ds.Tables[0].Rows.Count; i  )
    {
        budgetsActualsList.Add(
            new BudgetsActualsViewModel
             {
                 SelectedDepartment = ds.Tables[0].Rows[i]["Department"].ToString()
             }
        );
    }
    return budgetsActualsList;
}
 

Комментарии:

1. Вы пробовали копировать значения в другой список вместо передачи списка, возвращаемого методом?

2. @JamshaidKamran, нет, потому что, честно говоря, я не понимаю, почему у меня есть два свойства для моего выпадающего списка (я скопировал это из связанного примера) и получил исключение IEnumerable cast при попытке.

3. Хорошо, это понятно. Вы сохраняете значения в SelectedDepartment и получаете доступ к другому свойству, которое, очевидно, будет равно null.

4. Ваш BudgetsActualsViewModel класс Departments определен как тип IEnumerable<SelectListItem> , в то время как ваш репозиторий возвращает тип List<BudgetsActualsViewModel> для метода GetBudgetsActuals()

5. @JamshaidKamran, согласен. Но мне нужен пример кода в качестве ответа. Спасибо.

Ответ №1:

Итак, вы сохраняете значения в SelectedDepartment свойстве и получаете доступ к Departments списку. Который никогда не инициализируется, так что, очевидно, так и будет null .

Измените свой GetBudgetsActuals метод следующим образом:

 public BudgetsActualsViewModel GetBudgetsActuals()  
{
    ...
    BudgetsActualsViewModel budgetsActuals = new BudgetsActualsViewModel(){ Departments = new List<SelectListItem>() };
    // Query returning correct data from DB here

    for (int i = 0; i < ds.Tables[0].Rows.Count; i  )
    {
        budgetsActuals.Departments
                      .Add(new SelectListItem 
                          { 
                              Text = ds.Tables[0].Rows[i]["Department"].ToString(), 
                              Value = ds.Tables[0].Rows[i]["YourRowId"].ToString() 
                          });
    }
    return budgetsActuals;
}
 

И вот как должно выглядеть ваше представление:

 @model BudgetDemo.Models.BudgetsActualsViewModel
@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments))
 

Обратите внимание, мы избавились от foreach цикла. Нам нужно DropDownListFor() , чтобы метод вызывался только один раз.


Обновить

 public class BudgetsActualsViewModel
{
    [Display(Name = "Cost Center/Department")]
    [Required(ErrorMessage = "Cost Center/Department is required.")]
    [StringLength(62)]
    public string SelectedDepartment { get; set; }
    public List<SelectListItem> Departments { get; set; } // Modify it to list instead IEnumerable.
}
 

Комментарии:

1. ‘IEnumerable<SelectListItem>’ не содержит определения для ‘Add’, принимающего первый аргумент типа ‘IEnumerable<SelectListItem>’

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

3. Для «YourRowId» я вставил «SelectedDepartment» и получил ошибку: System. Исключение ArgumentException: столбец ‘SelectedDepartment’ не принадлежит таблице table

4. @IrishChieftain, это то, что вы должны ему передать. В вашей базе данных есть столбец ID, который в большинстве случаев является первичным ключом. Введите этот столбец

5. Возможно, вы захотите изменить модель, чтобы в ней были другие данные.