Razor Pages でセレクトボックスの asp-items を設定したが、ページ表示時に System.NullReferenceException 'Object reference not set to an instance of an object.' エラーが発生する - ASP.NET Core

Razor Pages でセレクトボックスの asp-items を設定して実行すると、ページ表示時に System.NullReferenceException 'Object reference not set to an instance of an object.' エラーが発生する現象と対処法を紹介します。

現象の確認

ASP.NET Core アプリケーションを作成し、次のコードを用意します。

コード

Pages/SelectBoxSetValueDoNotWork02.cshtml
@page
@model SimpleSelectBox.Pages.SelectBoxSetValueDoNotWork02Model
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{

}
<html>
  <head>
  </head>
  <body>
    <h2>セレクトボックスの値を設定するデモ</h2>
    <form method="post">
      <select asp-for="@Model.data.action" asp-items="@Model.UIItemsList"></select>
       <input type="submit" value="Exec"/>
    </form>
    <hr/>
    @if (Model.PostMessage != "")
    {
      <p>@Model.PostMessage</p>
    }
  </body>
</html>
Pages/SelectBoxSetValueDoNotWork02.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace SimpleSelectBox.Pages
{
  public class SelectBoxSetValueDoNotWork02Model : PageModel
  {
    public class ActionData
    {
      public int action { get; set; }
    }

    public SelectList UIItemsList { get; set; }

    [BindProperty]
    public ActionData data { get; set; }
        
    public string PostMessage;

    public SelectBoxSetValueDoNotWork02Model()
    {
      data = new ActionData();

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

    }

    public void OnGet()
    {

    }

    public void OnPost()
    {
      PostMessage = string.Format("選択:{0:d}", data.action); 

    }

  }
}
MyWItem.cs
namespace SimpleSelectBox
{
  public class MyWItem
  {
    public int id;
    public string name;
  }
}
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.Run();

解説

selectタグによるセレクトボックスをRazorPageに配置しています。 asp-itemsを指定し、動的にセレクトボックスの項目を作成しています。選択結果はページモデルのdataオブジェクトのactionメンバ変数に設定されます。
 <select asp-for="@Model.data.action" asp-items="@Model.investorList"></select>

実行結果

プロジェクトを実行し、(アプリケーションルートURL)/SelectBoxSetValueDoNotWork02 のページを表示すると、以下のエラーメッセージが表示されます。
エラーメッセージ
System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Microsoft.AspNetCore.Mvc.ViewFeatures

原因

MyWItemクラスのメンバーはメンバー変数ではなくプロパティとして実装する必要があります。
下記の元のコードはメンバ変数として実装されているため、実行時に例外が発生します。
  public class MyWItem
  {
    public int id;
    public string name;
  }

対処法

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

実行結果

プロジェクトを実行し (アプリケーションルートURL)/SelectBoxSetValueDoNotWork02 のページにアクセスします。 下図のページが表示されます。


セレクトボックスに項目が設定されています。


項目を選択し[Exec]ボタンをクリックします。


選択された項目のIDの値がページ下部に表示されます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2022-06-13
作成日: 2022-06-13
iPentec all rights reserverd.