質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

解決済

MVC5 Ajax.BeginForm の使い方について(部分ビュー更新)

Kai
Kai

総合スコア10

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

2回答

0リアクション

0クリップ

1184閲覧

投稿2022/01/31 10:54

編集2022/02/01 08:05

Ajax.BeginFormを利用して、部分ビューを更新したいです。
詳細は以下です。

やりたいこと

  1. ボタンクリックで部分ビュー更新
  2. 更新後再描画された部分ビューで連続してボタンクリックによる部分ビュー更新ができる

起きている問題

  1. 想定通りに部分ビューが置き換わらない(UpdateTargetの中だけでなくフォーム全体が描画される…詳細は下部コード『html(画面で見た更新後のhtml)』参照)
  2. 更新後の部分ビューでは連続してボタンクリックによる部分ビューの更新ができない

コード

html(_comment.cshtml)

<!-- // 厳密には cshtml --> @using(Ajax.BeginForm ( "Save", "Common", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "POST", UpdateTarget = "target-area" } ) { <div id="target-area"> @Html.AntiForgeryToken() <button name="save">保存</button> @Html.TextArea("text-area", Model.textData) </div> <!-- /#target-area --> }

c#(CommonController.cs)

[HttpPost] [ValidateAntiForgeryToken] public ActionResult Save() { // ここで非同期通信できているか確認 // 初回はif内へは入らず後続処理が正常動作していることから、 // 非同期通信になっていることを確認 if(!Request.IsAjaxRequest()) { return new EmptyResult(); } var textdata = Request.Form["text-area"]; var model = new TestModel(); model.textData = textdata; return PartialView ("_textarea", model); }

生成されたHtmlのコード(開発者ツールで確認)

html(画面で見た更新前のhtml)

<form action="/Common/Save" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace"> <div id="target-area"> <button name="save">保存</button> <textarea name="text-area"></textarea> </div> <!-- #target-area --> </form>

html(画面で見た更新後のhtml)

<form action="/Common/Save" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace"> <div id="target-area"> <form action="/Common/Save" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace"> <div id="target-area"> <button name="save">保存</button> <textarea name="text-area"></textarea> </div> <!-- #target-area --> </form> </div> <!-- #target-area --> </form>

その他情報

  • 初期表示時にボタンクリックしたときに、1回は非同期通信ができています。(Request.IsAjaxRequest()で確認)
  • 連続して(画面全体を再読み込みせずに)ボタンクリックすると非同期通信にならず、EmptyResult() が返されます。(新規でHtmlが生成されるのでイベントを追加しなければならないんだとは思いますが、Ajax.BeginFormを使った場合にどのように書けばいいかが分かりません。)
  • Microsoft.jQuery.Unobtrusive.Ajax はNugetでインストール済みです。
  • jquery.unobtrusive-ajax.js の参照は記述済みです。(ブラウザ開発者ツールでデバッグもできるので正しく読み込めていることを確認)
  • BundleConfig.cs の利用を禁止されており、以下を追記できていません。これが気がかりです。もしこれが原因の場合、対策はありますか?

c#(BundleConfig.cs)

bundles.Add(new ScriptBundle("~/bundles/jqueryajax").Include("~/Scripts/jquery.unobtrusive-ajax*"));
  • UpdateTargetId に該当するidを設定する要素の位置がformの外が良いのかとも思いましたが、以下リンク先の質問の回答でformの中に定義していたので真似ています。

<参考にした質問ページ>
https://teratail.com/questions/137630

環境

  • OS: Windows 10
  • IDE: Microsoft Visual Studio Professional 2019
  • 対象フレームワーク: .Net Framework 4.8
  • 使用対象ブラウザ: Chrome, Chromium Edge, FireFox

以上の問題を解消し、やりたいことの実現をするためにご助言いただきたく、よろしくお願い致します。



[追記] 

問題発生中のプロジェクトと同じ構成のコード

※以下のコードは問題発生中のものと同じ構成ですが、Web操作的には正常に動作します。
そのため、問題の原因がなおさら分からない状況にあります。

html(_Layout.cshtml)

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - マイ ASP.NET アプリケーション</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> </head> <body> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>&copy; @DateTime.Now.Year - マイ ASP.NET アプリケーション</p> </footer> </div> </body> </html>

 

html(Index.cshtml)

<div id="main"> <h2>Ajax 部分ビュー更新</h2> @Html.Partial("_app/_comment") </div>

 

html(_comment.cshtml)

@model WebAjaxTest.Controllers.ViewModel @using (Ajax.BeginForm("Save", "ForAjax", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "POST", UpdateTargetId = "replace-area"})) { <div id="replace-area"> @Html.AntiForgeryToken() <div class="button-area"> <button name="save">保存</button> </div> @Html.TextArea( "text-comment", Model.comment, new { @id = "comment-area" } ) </div> }

 

c#(HomeController)

using System.Web.Mvc; namespace WebAjaxTest.Controllers { public class HomeController : Controller { public ActionResult Index() { var vm = new ViewModel(); vm.comment = "初期表示"; return View(vm); } } // 記載か所が不適切だが取り急ぎの記述 public class ViewModel { public string comment { get; set; } } }

 

c#(ForAjaxController.cs)

using System.Web.Mvc; namespace WebAjaxTest.Controllers { public class ForAjaxController : Controller { [HttpPost] [ValidateAntiForgeryToken] public ActionResult Save() { if (!Request.IsAjaxRequest()) { return new EmptyResult(); } var comment = Request.Form["text-comment"]; var vm = new ViewModel(); // データなし if (comment == "") { vm.comment = "ブランクでした"; } else { vm.comment = comment + "(値が入っていたので正常更新です)"; } return PartialView("_app/_comment", vm); } } }

 

実行 前後 のHtmlソース(開発者ツールから取得)

html(保存ボタンクリック前)

<div id="main"> <h2>Ajax 部分ビュー更新</h2> <!--部分ビュー ここから--> <form action="/ForAjax/Save" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#replace-area" id="form0" method="post"> <div id="replace-area"> <input name="__RequestVerificationToken" type="hidden" value="b0X1izesGdcOFWj7Jbo2gOfgarQfXczwOOTRqL6KB2fYEEY21UblfUNkA68EzkZp6jUFK27Rq4vfWs4At-OCB3KlGClF4hCZ53ST7LTGrFo1"> <div class="button-area"> <button name="save">保存</button> </div> <textarea cols="20" id="comment-area" name="text-comment" rows="2">初期表示</textarea> </div> </form> <!--部分ビュー ここまで--> </div>

 
実行後はWeb操作は連続非同期処理できますが、以下のソースの置き換わり方が正しいのか気になります
(id=replace-area のdivが重複状態になってしまうため)

html(保存ボタンクリック後)

<div id="main"> <h2>Ajax 部分ビュー更新</h2> <!--部分ビュー ここから--> <form action="/ForAjax/Save" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#replace-area" id="form0" method="post"> <div id="replace-area"> <!--部分ビュー ここから--> <div id="replace-area"> <input name="__RequestVerificationToken" type="hidden" value="2XUuEFyWynlKr9_DLUzke0bAdh1faQX7qyCwWpsl2Zbu2_7v3Tok5vBJXUMGMpbJHlbuVgzRgjA8MRQI2YxFegM1UsIYneW-DipyhqGxVCA1"> <div class="button-area"> <button name="save">保存</button> </div> <textarea cols="20" id="comment-area" name="text-comment" rows="2" style="width: 344px; height: 55px;">初期表示(値が入っていたので正常更新です)</textarea> </div> <!--部分ビュー ここまで--> </div> </form> <!--部分ビュー ここまで--> </div>

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

SurferOnWww

2022/02/01 00:13

MVC4 ではなく MVC5 だと思いますが、であれば ASP.NET MVC 4 のタグは外してください。
SurferOnWww

2022/02/03 00:36

回答のコメントに書いた「Post/Redirect/Get パターンを使おうとして先の私のコードを書き換えた時」のコードが見つかって、質問に書いてある「一回目は OK だが二回目以降がダメ」が再現できました。後で回答欄に追記しておきます。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。