記事詳細


投稿日
2026年09月09日09時05分
タイトル

ASP.NET Core MVC: CreateViewのform内の親の<select asp-for="PaymentTypeId" class="form-control" asp-items="@(ViewData["PaymentTypeId"] as SelectList)">に「新規項目」を追加して、子の<select asp-for="PaymentMethodId" class="form-control" asp-items="@(ViewData["PaymentMethodId"] as SelectList)">に、「新規項目」が追加出来るようにする方法を教えてください。親テーブル名「PaymentTypes」子テーブル名「PaymentMethod」DB保存が必要です。

内容

なるほど、やりたいことは ASP.NET Core MVC の Create ビューで、親 <select> に「新規項目」を追加できるようにし、その場で子 <select> にも新規項目を追加し、DB に保存する ということですね。
これは 親子マスタの動的追加 + Ajax 連動 のパターンです。

以下に、完全な実装例 を示します。
(親:PaymentTypes、子:PaymentMethods

1. モデル定義

Csharp
// 親テーブル public class PaymentType { public int Id { get; set; } public string Name { get; set; } public ICollection<PaymentMethod> PaymentMethods { get; set; } } // 子テーブル public class PaymentMethod { public int Id { get; set; } public string Name { get; set; } public int PaymentTypeId { get; set; } public PaymentType PaymentType { get; set; } }

2. コントローラー

Csharp
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; public class PaymentsController : Controller { private readonly AppDbContext _context; public PaymentsController(AppDbContext context) { _context = context; } // Create GET public IActionResult Create() { ViewData["PaymentTypeId"] = new SelectList(_context.PaymentTypes, "Id", "Name"); ViewData["PaymentMethodId"] = new SelectList(Enumerable.Empty<SelectListItem>()); return View(); } // Create POST [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(PaymentMethod model) { if (ModelState.IsValid) { _context.PaymentMethods.Add(model); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Create)); } ViewData["PaymentTypeId"] = new SelectList(_context.PaymentTypes, "Id", "Name", model.PaymentTypeId); ViewData["PaymentMethodId"] = new SelectList(_context.PaymentMethods.Where(m => m.PaymentTypeId == model.PaymentTypeId), "Id", "Name", model.Id); return View(model); } // Ajax: 親選択時に子を取得 [HttpGet] public async Task<IActionResult> GetMethods(int paymentTypeId) { var methods = await _context.PaymentMethods .Where(m => m.PaymentTypeId == paymentTypeId) .Select(m => new { m.Id, m.Name }) .ToListAsync(); return Json(methods); } // Ajax: 親の新規追加 [HttpPost] public async Task<IActionResult> AddPaymentType(string name) { if (string.IsNullOrWhiteSpace(name)) return BadRequest("Name is required"); var type = new PaymentType { Name = name }; _context.PaymentTypes.Add(type); await _context.SaveChangesAsync(); return Json(new { id = type.Id, name = type.Name }); } // Ajax: 子の新規追加 [HttpPost] public async Task<IActionResult> AddPaymentMethod(int paymentTypeId, string name) { if (string.IsNullOrWhiteSpace(name)) return BadRequest("Name is required"); var method = new PaymentMethod { PaymentTypeId = paymentTypeId, Name = name }; _context.PaymentMethods.Add(method); await _context.SaveChangesAsync(); return Json(new { id = method.Id, name = method.Name }); } }

3. Create.cshtml

Razor
@model PaymentMethod @{ ViewData["Title"] = "Create Payment Method"; } <h2>Create Payment Method</h2> <form asp-action="Create" method="post"> <div class="form-group"> <label asp-for="PaymentTypeId"></label> <select asp-for="PaymentTypeId" class="form-control" asp-items="@(ViewData["PaymentTypeId"] as SelectList)" id="PaymentTypeId"> <option value="">-- Select --</option> </select> <button type="button" id="btnAddType" class="btn btn-sm btn-primary mt-1">+ 新規項目</button> </div> <div class="form-group"> <label asp-for="Name">Payment Method</label> <select asp-for="Id" class="form-control" asp-items="@(ViewData["PaymentMethodId"] as SelectList)" id="PaymentMethodId"> <option value="">-- Select --</option> </select> <button type="button" id="btnAddMethod" class="btn btn-sm btn-primary mt-1">+ 新規項目</button> </div> <button type="submit" class="btn btn-success">Save</button> </form> @section Scripts { <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> // 親変更時に子を取得 $("#PaymentTypeId").change(function () { var typeId = $(this).val(); $("#PaymentMethodId").empty().append('<option value="">-- Select --</option>'); if (typeId) { $.getJSON('/Payments/GetMethods', { paymentTypeId: typeId }, function (data) { $.each(data, function (i, item) { $("#PaymentMethodId").append($('<option>', { value: item.id, text: item.name })); }); }); } }); // 親の新規追加 $("#btnAddType").click(function () { var name = prompt("新しい支払いタイプ名を入力してください:"); if (name) { $.post('/Payments/AddPaymentType', { name: name }, function (data) { $("#PaymentTypeId").append($('<option>', { value: data.id, text: data.name, selected: true })); $("#PaymentTypeId").trigger("change"); }); } }); // 子の新規追加 $("#btnAddMethod").click(function () { var typeId = $("#PaymentTypeId").val(); if (!typeId) { alert("先に支払いタイプを選択してください。"); return; } var name = prompt("新しい支払い方法名を入力してください:"); if (name) { $.post('/Payments/AddPaymentMethod', { paymentTypeId: typeId, name: name }, function (data) { $("#PaymentMethodId").append($('<option>', { value: data.id, text: data.name, selected: true })); }); } }); </script> }

4. 実装ポイント

  • 親 <select> に「+ 新規項目」ボタンを付け、prompt() で名前を入力 → Ajax で DB 保存 → <select> に即反映。
  • 子 <select> も同様に「+ 新規項目」ボタンを付け、選択中の親 ID と一緒に Ajax 送信。
  • 親変更時に Ajax で子リストを再取得。
  • DB 保存はコントローラーの `AddPayment

Powered by Froala Editor

添付画像

画像はありません
Genreのカテゴリ-名
Views
編集 | 記事一覧