ページモデルのメンバ変数にRazorPagesのフォームをPOSTした値が代入されない現象について紹介します。
現象の確認
ASP.NET Coreアプリケーションを作成し、以下のRazorPagesを作成します。
コード
@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>
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 });
}
}
}
@page
@model RazorPagesPost.Pages.ResultModel
@{
}
<html>
<head>
</head>
<body>
<p>テストページ結果</p>
<div>@Model.ReceiveValue</div>
</body>
</html>
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;
}
}
}
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 属性を設定します。
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