WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

ASP.NET Core MVC と Ajax ライブラリ

by WebSurfer 2020年3月6日 21:10

.NET Framework の ASP.NET MVC5 アプリケーションでは AjaxHelper(Ajax.BeginForm, Ajax.ActionLink など)と Microsoft の Ajax ライブラリ jquery.unobtrusive-ajax.js を利用して、Ajax で部分ビューを呼び出してページ内の指定の場所に表示するなどのことが、JavaScript / jQuery のコードを書かなくても容易にできるようになっています。

Ajax で部分ビューを表示

同じことが ASP.NET Core 3.1 MVC でもできるだろうと思っていましたがダメでした。

MVC5 であれば、先の記事「MVC5 で AjaxHelper が働かない」で書きましたように NuGet から Microsoft.jQuery.Unobtrusive.Ajax をインストールすれば、AjaxHelper を使って目的が果たせます。

ところが、ASP.NET Core 3.1 MVC では、まず AjaxHelper が使えないようです。また、NuGet で Microsoft.jQuery.Unobtrusive.Ajax をインストールしても、肝心の jquery.unobtrusive-ajax.js が wwwroot に配置されません。(LibMan を使えということのようですが jquery.unobtrusive-ajax.js は登録されてないようです)

そこを無理やり(?) jquery.unobtrusive-ajax.js を使って Ajax で部分ビューを呼び出してページ内の指定の場所に表示するにはどうするかを以下に書きます。

(1) まず、jquery.unobtrusive-ajax.js を入手して以下の画像のように wwwroot 下のフォルダに配置します。

jquery.unobtrusive-ajax.js を配置

(2) 外部スクリプトファイル jQuery.js と上記 (1) の jquery.unobtrusive-ajax.js がダウンロードされるよう、View に script 要素を設定します。必ず jQuery.js が先に来るようにしてください。

_Layout.cshtml を使っていれば jQuery.js は設定されるようになっているので、View には jquery.unobtrusive-ajax.js だけ追加されるように設定すれば良いはずです。

(3) View のコードの form 要素に以下の属性を追加します。

data-ajax="true" data-ajax-mode="replace" data-ajax-update="#result"

その意味は jquery.unobtrusive-ajax.js を使って ajax で要求を出し、返ってきた応答で id が result の要素の中身を書き換えるということです。属性の説明については以下の記事が詳しいので参考にしてください。

Using jQuery Unobtrusive AJAX in ASP.NET Core Razor Pages

Controller と View のサンプルコードを以下に書いておきます。使っているのは Microsoft が提供する Northwind サンプルデータベースの Customers テーブルです。

その CompanyName をドロップダウンリストに表示し、ユーザーが選択してボタンをクリックすると指定した Customers のレコードの詳細を、部分ビューを呼び出して、それを指定した場所(下の View のコードで言うと <div id="result"></div> の中)に書き出すものです。

Controller / Action Method

using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace MvcCoreApp.Controllers
{
  public class AjaxController : Controller
  {
    private readonly NorthwindContext _context;

    public AjaxController(NorthwindContext context)
    {
      _context = context;
    }

    // jquery.unobtrusive-ajax.js の助けを借りて
    // 部分ビューで詳細 Customer データを表示
    public IActionResult Index()
    {
      // 全部取得すると長すぎるので Take(10) した
      var list = _context.Customers.Take(10);
      ViewData["customers"] =
        new SelectList(list, "CustomerId", "CompanyName");
      return View();
    }

    // 部分ビュー用のアクションメソッド
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Details(string customerid)
    {
      if (string.IsNullOrEmpty(customerid))
      {
        return NotFound();
      }

      var customer = _context.Customers.Find(customerid);

      if (customer == null)
      {
        return NotFound();
      }

      return PartialView(customer);
    }
  }
}

View (Index.cshtml)

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<form asp-action="Details" asp-controller="Ajax" 
      data-ajax="true" data-ajax-mode="replace" 
      data-ajax-update="#result" method="post">

    <select id="customerid" name="customerid" 
            asp-items="@ViewBag.customers">
    </select>

    <input type="submit" value="詳細表示" />

</form>

<div id="result"></div>

@section Scripts {
  <script src="...フォルダ.../jquery.unobtrusive-ajax.js">
  </script>

部分ビュー (Details.cshtml)

@model MvcCoreApp.Customers

<div>
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.CustomerId)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.CustomerId)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.CompanyName)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.CompanyName)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.ContactName)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.ContactName)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.ContactTitle)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.ContactTitle)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Address)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Address)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.City)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.City)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Region)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Region)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.PostalCode)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.PostalCode)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Country)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Country)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Phone)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Phone)
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Fax)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.Fax)
        </dd>
    </dl>
</div>

jquery.unobtrusive-ajax.js は ASP.NET Core MVC ではサポートされてないような気がしますが、上記のようにすれば一応使えます。

jquery.unobtrusive-ajax.js を使わなくても同等のことは jQuery ajax を使ってできます。それについては別の記事「jQuery ajax で部分ビューの呼出・表示」を見てください。

Tags: , , ,

CORE

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年3月  >>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar