ページモデルのメンバ変数にRazorPagesのフォームをPOSTした値が代入されない - C#

ページモデルのメンバ変数にRazorPagesのフォームをPOSTした値が代入されない現象について紹介します。

現象の確認

ASP.NET Coreアプリケーションを作成し、以下のRazorPagesを作成します。

コード

Input.cshtml
@page
@model RazorPagesPost.Pages.InputModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head>
  <meta name="viewport" content="width=device-width" />
  <title>Button</title>
</head>
<body>
  <div>Post Demo</div>
  <form method="post">
    Text:<input type="text" asp-for="TextData" /><br />
    <input type="submit" value="Button1" />
  </form>
</body>
</html>
Input.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesPost.Pages
{
  public class InputModel : PageModel
  {
    public string TextData;

    public void OnGet()
    {

    }
    public IActionResult OnPost()
    {
      return RedirectToPage("/Result", new { value = TextData });
    }
  }
}
Result.cshtml
@page
@model RazorPagesPost.Pages.ResultModel
@{
}
<html>
<head>
</head>
<body>
  <p>テストページ結果</p>
  <div>@Model.ReceiveValue</div>
</body>
</html>
Result.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesPost.Pages
{
  public class ResultModel : PageModel
  {
    public string ReceiveValue;

    public void OnGet(string value)
    {
      ReceiveValue = value;
    }
  }
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RazorPagesPost
{
  public class Startup
  {
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddRazorPages();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
      }

      app.UseRouting();

      app.UseEndpoints(endpoints =>
      {
        endpoints.MapRazorPages();
      });
    }
  }
}

実行結果

上記のプロジェクトを実行します。
Webブラウザで (アプリケーションルート)/Input URLにアクセスします。下図のページが表示されます。


テキストボックスに文字を入力します。入力後 [Button1] ボタンをクリックします。


(アプリケーションルート)/Result URLにリダイレクトします。「テストページ結果」の文字のみが表示されます。

解説

Result.cshtml のRazorPageでは @Model.ReceiveValue の記述があり、ページモデルのReceiveValue メンバ変数の値をページに表示する動作になっています。
<body>
  <p>テストページ結果</p>
  <div>@Model.ReceiveValue</div>
</body>

ページモデルのクラスにも、ReceiveValue のメンバ変数があり、受け取った値をメンバ変数に代入する処理を実装しています。
  public class ResultModel : PageModel
  {
    public string ReceiveValue;

    public void OnGet(string value)
    {
      ReceiveValue = value;
    }
  }

原因

デバッグを進めると、Input.cshtml ページのOnPost時に、TextData メンバ変数に値が代入されていないことが確認できます。
  public string TextData;

  public IActionResult OnPost()
  {
    return RedirectToPage("/Result", new { value = TextData });
  }
フォームを POST された値をページモデル側で受け取るためには、受け取る変数はメンバ変数ではなく、プロパティとして宣言する必要があります。メンバ変数ではPOSTした値を受け取れません。

修正方法

Input.cshtml のTextData メンバ変数をプロパティに変更します。また、プロパティに BindProperty 属性を設定します。
Input.cshtml.cs (修正版)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesPost.Pages
{
  public class InputModel : PageModel
  {
    [BindProperty]
    public string TextData { get; set; }

    public void OnGet()
    {

    }
    public IActionResult OnPost()
    {
      return RedirectToPage("/Result", new { value = TextData });
    }
  }
}

実行結果

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


テキストボックスに文字を入力します。入力後 [Button1] ボタンをクリックします。


(アプリケーションルート)/Result URLにリダイレクトします。「テストページ結果」の下にテキストボックスに入力した文字列が表示されます。


ページモデルクラスにプロパティを宣言することで、フォームのPOST内容を受け取ることができました。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2021-03-29
作成日: 2021-03-29
iPentec all rights reserverd.