Binding DropDownList từ cơ sở dữ liệu

Nov 24 2020

Tôi đang xây dựng một dạng xem sẽ hiển thị dữ liệu dạng bảng dựa trên các lựa chọn từ hai danh sách thả xuống, danh sách đầu tiên chọn các phòng ban được điền từ cơ sở dữ liệu. Thứ hai là danh sách thả xuống tĩnh cho "Năm" mà tôi chưa có. Có những câu trả lời cho những câu hỏi tương tự, nhưng tôi đã xem xét chúng và thử mọi thứ. Tôi đã đến mức nhận được một ngoại lệ rỗng trong chế độ xem nơi tôi tạo đánh dấu cho danh sách thả xuống.

Lượt xem:

Các phòng ban đang trở lại dưới dạng rỗng. Tôi mới làm quen với MVC và tổng hợp điều này lại với nhau từ các ví dụ trực tuyến . Tôi đoán mô hình của tôi là sai.

@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; }
}

Bộ điều khiển:

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

Lớp Kho lưu trữ:

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;
}

Trả lời

1 JamshaidK. Nov 24 2020 at 06:13

Vì vậy, bạn đang lưu các giá trị trong thuộc SelectedDepartmenttính và truy cập Departmentsdanh sách. Mà không bao giờ được khởi tạo nên rõ ràng là như vậy null.

Sửa đổi GetBudgetsActualsphương pháp của bạn như sau:

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;
}

Và đây là cách Chế độ xem của bạn sẽ trông như thế nào:

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

Lưu ý, chúng tôi đã thoát khỏi foreachvòng lặp. Chúng ta cần DropDownListFor()phương thức chỉ được gọi một lần.


CẬP NHẬT

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.
}