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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Razor

RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

Q&A

解決済

1回答

2928閲覧

Ajax.BeginFormでの部分ビュー更新について

nepia

総合スコア30

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Razor

RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

0グッド

0クリップ

投稿2018/07/02 15:49

編集2018/07/03 04:51

いつもお世話になっております。
ASP.NET MVCの部分ビューの動的更新について、皆様のお力をお貸しいただきたいです。

開発環境
OS : Windows10
.NET FrameWork : 4.5.2
Visual Studio : 2015 Professonal
Visual Studioプロジェクト : ASP.NET Web Application(.NET FrameWork)
プロジェクトテンプレート : MVCを指定
実行環境 : IIS(Visual Studioでの実行時)
Ajax.BeginFormを使用する為の参照設定 : NuGet => Microsoft.jQuery.Unobtrusive.Ajax 3.2.5
JQueryの読込も正しく行っております。

現在、以下のソースにて、問題が発生しております。

Test/Index.cshtml

cshtml

1<div> 2 @Html.Partial("_List", Model) 3</div>

Test/_List.cshtml

cshtml

1@using BootstrapSite1.Models.Test 2@model TestViewModel 3 4@using (Ajax.BeginForm("Delete", "Test", 5 new AjaxOptions 6 { 7 InsertionMode = InsertionMode.Replace, 8 HttpMethod = "POST", 9 UpdateTargetId = "system-list", 10 11 })) 12{ 13 <table> 14 <tr> 15 <th>id</th> 16 <th>name</th> 17 <th>削除</th> 18 </tr> 19 @for(int i = 0; i < Model.SystemList.Count; i++) 20 { 21 <tr> 22 <td> 23 @Html.DisplayFor(m=>m.SystemList[i].Id) 24 @Html.HiddenFor(m=>m.SystemList[i].Id) 25 </td> 26 <td>@Html.TextBoxFor(m=>m.SystemList[i].Name)</td> 27 <td> 28 <button type="submit" name="idx" value="@i">削除</button> 29 </td> 30 </tr> 31 } 32 </table> 33} 34```  35 36Model 37```C# 38using System.Collections.Generic; 39using System.Data; 40using System.Text; 41 42namespace BootstrapSite1.Models.Test 43{ 44 public class SystemModel 45 { 46 public int Id { get; set; } 47 48 public string Name { get; set; } 49 50 } 51 public class TestViewModel 52 { 53 public List<SystemModel> SystemList { get; set; } 54 55 public TestViewModel () 56 { 57 this.SystemList = new List<SystemModel>(); 58 } 59 60 public void SetSystemList() 61 { 62 this.SystemList.Add(new SystemModel { Id = 1, Name = "1" }); 63 this.SystemList.Add(new SystemModel { Id = 2, Name = "2" }); 64 this.SystemList.Add(new SystemModel { Id = 3, Name = "3" }); 65 } 66}

Controller

C#

1using System.Collections.Generic; 2using System.Linq; 3using System.Web.Mvc; 4 5namespace BootstrapSite1.Controllers 6{ 7 public class TestController: Controller 8 { 9 public ActionResult Index() 10 { 11 TestViewModel model = new TestViewModel (); 12 model.SetSystemList(); 13 return View(model); 14 } 15 16 public PartialViewResult Delete(TestViewModel model, int idx) 17 { 18 List<SystemModel> list = model.SystemList; 19 list.RemoveAt(idx); 20 model.SystemList = list; 21 return PartialView("_List", model); 22 } 23 } 24}

上記のソースを実行した場合、画面には以下の表が表示されます。

idname削除
11削除
22削除
33削除

しかし、1行目の削除ボタンを実行するした場合

idname削除
21削除
33削除

上記の様に、部分的に再描画されますが、
@Html.HiddenForまたはTextBoxForなど出力している箇所が、前回の値を参照してしまっているような状態です。
部分ビュー出力時にデバックで追いかけても前回データはModelから削除されている為、前回値が表示されるのが何故か理解できません。

どうすれば、ビューが正しく更新されますでしょうか。

よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/07/02 22:17

MVC4 のタグがついてますが 4 に間違いないですか? 違う場合は付け直してください。他にASP.NET, ASP.NET MVC Framework というのがあります。
退会済みユーザー

退会済みユーザー

2018/07/02 22:22

それから、あなたの開発環境を書いてください。OS, .NET, MVC, Visual Studio のバージョン、テンプレートは何を使ったか、開発用サーバーは何かなどの情報は重要です。
退会済みユーザー

退会済みユーザー

2018/07/03 01:21

BootstrapSite1.Utility.Convert とか BootstrapSite1.Utility.Database という内容不明な名前空間(?)がコードに書かれていますが、今回の話とは直接関係ない(無視してよい)のですか?
nepia

2018/07/03 01:26

ご指摘頂いた件を修正させて頂きました。
nepia

2018/07/03 01:27

BootstrapSite1.Utility.Convert とか BootstrapSite1.Utility.Databaseにつきまして、未使用のusingですので、無視して頂いて結構です。
退会済みユーザー

退会済みユーザー

2018/07/03 02:52

意味不明の名前が多々あるのですが・・・ アクションメソッド public ActionResult Index() に対するビューが「View」で、「View」のコードの @Html.Partial("_List", Model) の _List が「部分View」、Model がアクションメソッドの return View(model); の model ですか?
退会済みユーザー

退会済みユーザー

2018/07/03 02:55

「Ajax.BeginFormを使用する為の参照設定 : NuGet => Microsoft.jQuery.Unobtrusive.Ajax 3.2.5」とのことですが、NuGet パッケージのインストールだけでなく、参照設定も jQuery 都の順番などを含めて間違いなくされていると理解して良いですか?
nepia

2018/07/03 04:52

上記のご指摘の件、修正させて頂きました。また、JQueryの読み込み順序もAJaxとして非同期更新が可能なので、問題ないと思われます。
guest

回答1

0

ベストアンサー

上記のご指摘の件、修正させて頂きました。

まだはっきりしませんが、上の質問に対する先の私のコメント、

アクションメソッド public ActionResult Index() に対するビューが「View」で、「View」のコードの @Html.Partial("_List", Model) の _List が「部分View」、Model がアクションメソッドの return View(model); の model ですか?

・・・は合っていると理解してレスしておきます。理解が違っていたらどこがどう違うか連絡ください。

たぶん ajax 呼び出しになっていないと思いますが、そこは今回の問題、

@Html.HiddenForまたはTextBoxForなど出力している箇所が、前回の値を参照してしまっているような状態です。

・・・には直接の関係はなさそうなのでちょっと置いときます。(後述します)

[削除]ボタンをクリックした結果で、何故 LabelFor と HiddenFor / TextBoxFor の値が違うかは以下の記事に書いてある通りの理由だと思います。

EditorFor と DisplayFor の違い
http://surferonwww.info/BlogEngine/post/2013/03/27/editorfor-and-displayfor-display-different-values.aspx

HiddenFor / TextBoxFor については、POST された値が ModelState ディクショナリ(model ではない)に格納されていて、Html Helper はまず ModelState ディクショナリを調べて、そこに値があればそれを表示するようになっています。

上の記事にも書いてありますが、試しに Delete アクションメソッドに以下のコードを追加してみてください。(これを解決策としていいかどうかは別の話ですよ)

if (ModelState.IsValid) { ModelState.Clear(); }

これで期待通りになれば上の記事の話が当たりです。

そこが解決できても ajax 呼び出しになっていなそうな点と、Ajax.BeginForm の使い方が正しくない点は訂正が必要だと思います。

また、JQueryの読み込み順序もAJaxとして非同期更新が可能なので、問題ないと思われます。

とのことですが、動いているように見えるだけで ajax を使って非同期更新はできてない様な気がします。

NuGet パッケージのインストールだけでなく、参照設定もきちんとしないとダメです。以下の記事に書いてるように BundleConfig.cs への登録と View での @Scripts.Render("~/bundles/xxx") の追加が必要ですが、きちんとやってますか?

MVC5 で AjaxHelper が働かない
http://surferonwww.info/BlogEngine/post/2018/05/28/ajaxhelpers-do-not-work-on-mvc5-application-created-by-visual-studio-template.aspx

それから、Test/_List.cshtml での Ajax.BeginForm の使い方ですが、UpdateTargetId = "system-list" で指定される部分が書き換わるので、そこをきちんと書かないとダメです。

質問者さんの例では Test/_List.cshtml のコードの table 要素全体を <div id="system-list"> ... </div> で囲うというようにしないと期待した結果は得られないはずです。

投稿2018/07/03 05:23

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nepia

2018/07/03 05:52

ありがとうございました! ModelState.Clear()処理を記入することで、期待通りの動作となりました。
len_souko

2018/07/03 15:46

TextBoxに入力した値が初期化されると言われて困る気がする
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問