データベースからのDropDownListのバインド

Nov 24 2020

2つのドロップダウンリストからの選択に基づいて表形式のデータを表示するビューを作成しています。最初に部門を選択すると、データベースからデータが入力されます。2つ目は、まだ取得していない「年」の静的ドロップダウンリストです。同様の質問に対する答えがありますが、私はそれらを見て、すべてを試しました。ドロップダウンリストのマークアップを作成したビューでnull例外が発生するところまで来ました。

見る:

部門は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 JamshaidK. Nov 24 2020 at 06:13

したがって、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()メソッドを1回だけ呼び出す必要があります。


更新

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