Razor Pages でforループでフォーム要素を作成し配列プロパティにバインドする - ASP.NET Core

Razor Pages でforループでフォーム要素を作成し配列プロパティにバインドするコードを紹介します。

概要

こちらの記事では、 フォームの入力コントロールにページモデルクラスの配列プロパティをバインドするコードを紹介しました。

入力コントロールの数が多い場合は、forループなどで動的にコントロールを作成したい場合があります。 この記事では、forループを利用して動的にコントロールを作成し、配列プロパティにバインドするコードを紹介します。

プログラム例

ASP.NET Core アプリケーションを作成します。

コード

下記コードを作成します。
ArrayBindLarge.cshtml
@page
@model BindPropertyArray.Pages.ArrayBindLargeModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 
@{
}
<html>
  <head></head>
  <body>
    <h3>配列のBindPropertyのデモ</h3>
    <form method="post">
      @{
        for (int i=0; i<1000; i++){
          <input type="text" asp-for="@Model.values[i]"/><br/>
        }
        }
        <input type="submit" value="Exec"/>
    </form>

    <hr/>
    @{
        for (int i=0; i<1000; i++){
          <p>@Model.outtext[@i]</p>
        }
    }

  </body>
</html>
ArrayBindLarge.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace BindPropertyArray.Pages
{
  public class ArrayBindLargeModel : PageModel
  {
    [BindProperty]
    public string[] values { get; set; }

    public string[] outtext;

    public ArrayBindLargeModel()
    {
      values = new string[1000];
      outtext = new string[1000];
    }

    public void OnGet()
    {
      for (int i = 0; i < 1000; i++) {
        values[i] = string.Format("値:{0:d}",i);
      }
    }

    public void OnPost()
    {
      for (int i = 0; i < 1000; i++) {
        outtext[i] = values[i];
      }
    }

  }
}
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();

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

解説

Razor Pagesのforループでテキストボックスを 1,000個ページに配置します。 asp-for属性にバインドするプロパティを設定します。今回は配列プロパティを指定するため、@Model.values[i] を設定します。
for (int i=0; i<1000; i++){
    <input type="text" asp-for="@Model.values[i]" value="値:@i"/><br/>
}

フォームのサブミットボタンをクリックすると、ページモデルのOnPost()メソッドが呼び出されます。
1,000個のテキストボックスにバインドされた配列プロパティを出力の配列プロパティに代入します。
public void OnPost()
{
  for (int i = 0; i < 1000; i++) {
    outtext[i] = values[i];
  }
}

出力部分もforループでページに出力する配列プロパティの値を表示します。
@{
    for (int i=0; i<1000; i++){
      <p>@Model.outtext[@i]</p>
    }
}
補足
Razor Pageの forループ部分を以下のコードにした場合は正しく動作しませんので注意が必要です。
<form method="post">
  @{
    for (int i=0; i<1000; i++){
      <input type="text" asp-for="values[@i]"/><br/>
    }
  }
  <input type="submit" value="Exec"/>
</form>
下記のHTMLが生成されます。
<form method="post">
  <input type="text" value="値:0" data-val="true" data-val-required="The Int32 field is required." id="i" name="i" /><br/>
  <input type="text" value="値:1" id="i" name="i" /><br/>
  <input type="text" value="値:2" id="i" name="i" /><br/>
  <input type="text" value="値:3" id="i" name="i" /><br/>
  <input type="text" value="値:4" id="i" name="i" /><br/>
  <input type="text" value="値:5" id="i" name="i" /><br/>
  <!-- 中略 -->
  <input type="submit" value="Exec"/>
  <input name="__RequestVerificationToken" type="hidden" value="(トークン値)" />
</form>

実行結果

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


下にスクロールします。テキストボックスが1,000個作成されていることが確認できます。テキストボックス下部の[Exec]ボタンをクリックします。


クリックするとテキストボックスに入力されている値が、ページの下部に表示されます。


テキストボックスの値も1,000個ページに表示されています。


HTMLは以下のコードで生成されます。
<form method="post">
  <input type="text" value="値:0" id="values_0_" name="values[0]" /><br/>
  <input type="text" value="値:1" id="values_1_" name="values[1]" /><br/>
  <input type="text" value="値:2" id="values_2_" name="values[2]" /><br/>
  <input type="text" value="値:3" id="values_3_" name="values[3]" /><br/>
  <input type="text" value="値:4" id="values_4_" name="values[4]" /><br/>
  <input type="text" value="値:5" id="values_5_" name="values[5]" /><br/>
  <!-- 中略 -->
  <input type="submit" value="Exec"/>
  <input name="__RequestVerificationToken" type="hidden" value="(トークン値)" />
</form>

大量のテキストボックスをforループで作成しページに配置し、配列プロパティにバインドして、値の取得ができることを確認しました。

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