Razor Pagesでセレクトボックス、ドロップダウンリストに値を動的に設定すると "System.NullReferenceException: 'Object reference not set to an instance of an object.'"エラーが発生する - ASP.NET Core

Razor Pagesでセレクトボックス、ドロップダウンリストに値を動的に設定すると "System.NullReferenceException: 'Object reference not set to an instance of an object.'"エラーが発生する原因と対処法を紹介します。

現象

Razor Pagesのページを表示するとセレクトボックスの箇所で次のエラーが発生します。
エラーメッセージ
System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Microsoft.AspNetCore.Mvc.ViewFeatures
  スタック トレース:
  ...

再現コード

SelectBoxNullErrorDemo.cshtml
@page
@model SimpleSelectBox.Pages.SelectBoxNullErrorDemoModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head>

</head>
<body>
  <h2>セレクトボックスの値を設定するデモ</h2>
  <form method="post">
        <select asp-for="@Model.SelectValue" asp-items="@Model.ListItem"></select>
        <input type="submit" value="Exec"/>
  </form>
    @if (Model.Output != "") {
    <p>@Model.Output が選択されました。</p>
    }
</body>
</html>
SelectBoxNullErrorDemo.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace SimpleSelectBox.Pages
{
  public class SelectBoxNullErrorDemoModel : PageModel
  {
    [BindProperty]
    public int SelectValue { get; set; }
    public SelectList ListItem { get; set; }
    public string Output { get; set; } = "";

    public SelectBoxNullErrorDemoModel()
    {
      List<MyWItem> itemslist = new List<MyWItem>();
      itemslist.Add(new MyWItem { id = 1, name = "AAAA" });
      itemslist.Add(new MyWItem { id = 2, name = "BBBB" });
      ListItem = new SelectList(itemslist, "id", "name");
    }

    public void OnGet()
    {

    }

    public void OnPost()
    {
      Output = Convert.ToString(SelectValue);
    }

  }
}
MyWItem.cs
namespace SimpleSelectBox
{
  public class MyWItem
  {
    public int id;
    public string name;
  }
}
プロジェクトを実行し、(アプリケーションルート)/SelectBoxNullErrorDemo のURLにアクセスすると、先のSystem.NullReferenceException 例外が発生します。

原因

SelectListを作成する際に与えるSystem.Collections.IEnumerableオブジェクトの要素のオブジェクトがプロパティでないためアクセスできないことが原因です。

先の例では、List<MyWItem> 型の itemslist を作成し、"id"メンバをセレクトボックス選択時の値とし、"name"メンバをセレクトボックスの表示文字列に設定しています。
   ListItem = new SelectList(itemslist, "id", "name");

参照される MyWItemクラスでは、idとnameのメンバ変数が実装されていますが、プロパティとして実装されていないため、 アクセスができずに、先のSystem.NullReferenceException 例外が発生します。
  public class MyWItem
  {
    public int id;
    public string name;
  }

対処法

MyWItemクラスのメンバ変数をプロパティの実装に変更します。
MyWItem.cs
namespace SimpleSelectBox
{
  public class MyWItem
  {
    public int id { get; set; }
    public string name { get; set; }
  }
}

修正後、プロジェクトを実行しページを表示すると例外が発生せずページが表示できます。


ヒント
セレクトボックスの値が表示されない場合は、selectタグの書式に問題のあるケースが多いです。 詳しくはこちらの記事を参照してください。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2023-05-07
作成日: 2023-05-02
iPentec all rights reserverd.