Razor Pagesで部分更新する方法についてのアイキャッチ画像

Razor Pages で 部分更新 する方法について

Razor Pagesは画面全体の更新を容易に行えます。しかし、画面を部分的に更新するには、どうすればよろしいでしょうか。ここではformタグを利用して部分的な更新方法を紹介していきます。

対象環境

当記事は以下の環境で作成しています。

  • Visual Studio 2022
  • .Net 6 ※.Net Core 3.1以降
  • Razor Pages
  • MVC ※JavaScriptのみ

1.メイン画面の準備

メイン画面を追加するためには、Pages フォルダ を選択し「Ctrl + Shift + A」とキーボードを打ちます。マウスの場合は、Pages フォルダ を右クリックし「追加(D)」>「新しい項目(W)」を選択します。

以下のような画面が表示されたときは、「すべてのテンプレートの表示(T)」を選択してください。

新しい項目の追加(コンパクト ビュー表示)

「新しい項目の追加」が、表示されたら「Razor ページ – 空」を選択し追加していきます。今回は「Index.cshtml」で追加していきます。

新しい項目の追加(すべてのテンプレート表示)

2.部分ビューの準備

部分ビューの追加は、メイン画面と同じようにPages フォルダ に新しい項目を追加していきます。部分ビューは「新しい項目の追加」から「Razor ビュー – 空」を選択して追加していきます。今回は「_Result.cshtml」で追加していきます。

Razorビュー(空)の追加

3.サーバー処理を追加

サーバー処理を追加していきます。ここでは二つの数値を足して結果を表示できるようにします。

  1. メイン画面の値を受け取れるようにプロパティを用意します。ここでは変数名を「Argument1」「Argument2」にします。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace SamplePages.Pages
{
    public class IndexModel : PageModel
    {
        /// <summary>
        /// メイン画面から値を受け取ります。
        /// </summary>
        [BindProperty]
        public int Argument1 { get; set; } = 0;

        /// <summary>
        /// メイン画面から値を受け取ります。
        /// </summary>
        [BindProperty]
        public int Argument2 { get; set; } = 0;

        public IndexModel()
        {
        }

        public void OnGet()
        {
        }
    }
}
  1. 返却用のプロパティを用意します。ここでは変数名を「Result」にします。
        public int? Result { get; set; }
  1. 部分ビューを更新する場所を用意していきます。メソッド名はPost通信を行うために「OnPost~」から始まるようにします。「OnPost」より後の部分がハンドラ名になり呼び出す際に利用します。Partialメソッドは、第一引数に部分ビュー・第二引数に部分ビューに渡したい値を渡していきます。
        /// <summary>
        /// 部分ビューを更新します。
        /// </summary>
        /// <returns></returns>
        public IActionResult OnPostCalculation()
        {
            Result = Argument1 + Argument2;
            return Partial("_Result", Result);
        }

完成した内容

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace SamplePages.Pages
{
    public class IndexModel : PageModel
    {
        /// <summary>
        /// メイン画面から値を受け取ります。
        /// </summary>
        [BindProperty]
        public int Argument1 { get; set; } = 0;

        /// <summary>
        /// メイン画面から値を受け取ります。
        /// </summary>
        [BindProperty]
        public int Argument2 { get; set; } = 0;

        public int? Result { get; set; }

        public IndexModel()
        {
        }

        public void OnGet()
        {
        }

        /// <summary>
        /// 部分ビューを更新します。
        /// </summary>
        /// <returns></returns>
        public IActionResult OnPostCalculation()
        {
            Result = Argument1 + Argument2;
            return Partial("_Result", Result);
        }
    }
}

4.メイン画面の作成

メイン画面を作成していきます。サーバー処理の呼び出し部分 と 更新部分に分けて説明していきます。

  1. サーバー処理の呼び出しには formタグ を利用します。URLの指定には action属性 を使いますが、asp-page-handler属性 を利用することでURLを自動生成できます。ハンドラ名は先ほど作成した「OnPost」より後の部分を指定します。
@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<!-- サーバー処理の呼び出し部分 -->
<form method="post" asp-page-handler="Calculation">
    <input asp-for="Argument1" type="number" />
    <span>+</span>
    <input asp-for="Argument2" type="number" />
    <button>計算</button>
</form>
  1. 更新部分には Html.PartialAsyncメソッド を利用します。第一引数には部分ビュー・第二引数にはモデルを指定します。更新を指定する場所が必要になりますので、 Html.PartialAsyncメソッド を divタブ で囲っておきます。
<!-- 更新部分 -->
<div id="result-area">
    @await Html.PartialAsync("_Result",Model.Result)
</div>

完成した内容

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<!-- サーバー処理の呼び出し部分 -->
<form method="post" asp-page-handler="Calculation">
    <input asp-for="Argument1" type="number" />
    <span>+</span>
    <input asp-for="Argument2" type="number" />
    <button>計算</button>
</form>

<!-- 更新部分 -->
<div id="result-area">
    @await Html.PartialAsync("_Result",Model.Result)
</div>

5.部分ビューの作成

部分ビューを作成していきます。

@model int?
@{
}

<span>=</span>
@if (Model.HasValue)
{
    <span>@Model</span>
}
else
{
    <span>計算ボタンをクリックしてください。</span>
}

6.サーバー処理の呼び出し処理の作成

サーバー処理の呼び出すためにJavaScriptを利用します。ここでは jQueryを利用していきます。そのため、ここで作成したJavaScriptは、jQueryより後に読み込ませてください。

  1. サーバー処理の呼び出しには、formタグ を利用しています。このままでは画面遷移されるため、formタグ で submitイベント が発火されたときに formタグ の処理停止させます。
$(() => {
    $(document).on("submit", "form", function (e) {
        // formタグの処理停止
        e.preventDefault();
    });
});
  1. formタグ の処理を止めましたが、このままではサーバー処理を呼び出せません。そこでAjaxを利用していきます。値の取得に FormData を利用することで、値を取得する際の手間を省けます。
$(() => {
    $(document).on("submit", "form", function (e) {
        // formタグの処理停止
        e.preventDefault();

        const elem = $(this);
        // サーバーの通信情報取得
        const url = elem.prop("action");
        const method = elem.prop("method");
        // 値の取得
        const data = new FormData(this);

        // Ajax通信
        $.ajax(url, {
            type: method,
            data: data,
            contentType: false,
            processData: false
        }).done((starus, starusText, headers) => { 
        });
    });
});
  1. 最後にメイン画面の更新部分にHTMLを配置していきます。
$(() => {
    $(document).on("submit", "form", function (e) {
        // formタグの処理停止
        e.preventDefault();

        const elem = $(this);
        // サーバーの通信情報取得
        const url = elem.prop("action");
        const method = elem.prop("method");
        // 値取得
        const data = new FormData(this);

        // Ajax通信
        $.ajax(url, {
            type: method,
            data: data,
            contentType: false,
            processData: false
        }).done((starus, starusText, headers) => {
            // どこに追加するか位置を指定
            $("#result-area").html(starus);
        });
    });
});

実行してみよう

計算ボタンを選択してみてください。画面が再描画されずに計算ができれば完成です。

  • 初回表示時
実行結果(表示時)
  • 計算ボタン選択時
実行結果(実行時)