ASP.NET MVCの動的フォーム

多くの場合、ユーザーはいくつかの追加オブジェクトに関する情報を見つける必要がありますが、その数は事前にはわかりません。 このために、動的フォームが使用され、そのフィールドはクライアントマシンのJavaScriptコードによって作成されます。 Controller-Viewバンドルで動作するasp.net mvcでは、型付きオブジェクトを使用します。 ClassBinderクラスは、クライアントから受信した要求の値を型付きオブジェクトに変換することに関与します。 単純なオブジェクトの場合、これは非常に簡単なタスクです。 ただし、パラメータ名が事前に不明な動的データを正しく処理する方法。 この投稿は、この問題の解決に専念しています。







asp.net MVCでは、コントローラーは、入力されたデータオブジェクトを渡すことにより、モデルの変更をビューに通知します。



public class Customer { public int CustomerID { get; set; } // Unique key public string Name { get; set; } }
      
      







ビューでのデータ転送:

 [AcceptVerbs(HttpVerbs.Get)] public ViewResult CustomerView() { return View(new Customer { CustomerID = 14, Name = "Papa Carlo"}); }
      
      







GiftView.aspxビューで、このオブジェクトの値を表示します。

 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyNamespace.Customer>" %> <asp:Content ID="mainContent" ContentPlaceHolderID="MainContent" runat="server"> ID : <%= Html.Encode("CustomerID") %><br/> Name : <%= Html.Encode("Name") %><br/> </asp:Content>
      
      







また、asp.net MVCでは、コントローラーのデータ処理メソッドの前にAcceptVerbs属性を使用して、GET要求とPOST要求を別々に使用します。 POSTリクエストに含まれるデータはModelBinderによって処理され、オブジェクトを初期化します。オブジェクトは、データを処理するためのメソッドに入力されます。



 [AcceptVerbs(HttpVerbs.Get)] public ActionResult EditCustomer(int idCustomer) { //   Customer     idCustomer return View(Customer); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult EditCustomer(Customer customer) { if (ModelState.IsValid) { //     } return View(customer); }
      
      





このコントローラーメソッドのビューはどこにありますか。



 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyNamespace.Customer>" %> <asp:Content ID="mainContent" ContentPlaceHolderID="MainContent" runat="server"> <% using (Html.BeginForm()) { %> <%= Html.Hidden("CustomerID") %><br/> Name : <%= Html.TextBox("Name") %><br/> <input type="submit" value="Save" /> <% } %> </asp:Content>
      
      







使用するのは非常に便利ですが、動的なフォームに入力する必要がある場合には1つの問題があります。 フィールドを追加するには、JavaScriptを使用します。これにより、フィールドが生成されます。 しかし、タイプされたオブジェクトを取得するためにそれらをサーバーに正しく転送する方法は? この状況にはいくつかの解決策があります。 しかし、最初に、次の形式で作業するオブジェクトを拡張します。



 public class Ownership { public string Name { get; set; } public int Price {get; set; } } public class Customer { ... public List<Ownership> Ownerships { get; set; } }
      
      







最初の方法:

POST要求のハンドラーメソッドではパラメーターを受け入れませんが、Request.Params(NameValueCollection)プロパティを手動で処理します。

2番目の方法:

POSTリクエストのハンドラーメソッドで、FormCollectionパラメーターを受け入れ、このパラメーターを再度手動で処理します。

3番目の方法:

データ処理のバージョン(ModelBinder)を作成し、特定のタイプのデータを処理に追加します。



しかし、まだ4番目の方法があります-ビューに正しいデータ名を提供し、新しいフィールドの作成を正しく記述し、標準のModelBinderにそれらを処理する作業を提供し、入力でデータが既に入力されたCustomerタイプのオブジェクトを取得します。 したがって、EditCustomerビューは次のとおりです。



 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyNamespace.Customer>" %> <asp:Content ID="mainContent" ContentPlaceHolderID="MainContent" runat="server"> <% using (Html.BeginForm()) { %> <%= Html.Hidden("CustomerID") %><br/> Name : <%= Html.TextBox("Name") %><br/> <div class="add-ownership" id="AddOwnership">Add</div> <div id="Ownerships"> <% int index = 0; foreach (var ownership in Model.Ownerships) { %> <div class="ownership-container" id="OwnershipContainer<%= Html.Encode(index) %>"> Name : <%= Html.TextBox("Ownerships[" + index.ToString() + "].Name")%> Price : <%= Html.TextBox("Ownerships[" + index.ToString() + "].Price")%> <div class="remove-ownership">Remove</div> <%} %> </div> <% index++; } %> </div> <input type="submit" value="Save" /> <% } %> // javascript      ( . ) <script type="text/javascript"> var OwnershipsCount = <%= Model.Ownerships.Count.ToString() %>; </script> </asp:Content>
      
      







ここで、追加のフィールドを追加および削除するためにjqueryを正しく説明します。

 $().ready(function() { ///Add/Remove $("#AddOwnership").click(AddOwnership); $(".remove-ownership").click(RemoveOwnership); });
      
      







次に、追加する関数について説明します。

 function AddOwnership() { //  var OwnershipContainer = $("<div/>").attr("class", "ownership-container").attr("id", "OwnershipContainer" + OwnershipsCount).appendTo("#Ownerships"); OwnershipContainer.text(" Name : "); $("<input/>").attr("type", "text").attr("name", "Ownerships[" + OwnershipsCount + "].Name").attr("id", "Ownerships[" + OwnershipsCount + "]_Name").appendTo(OwnershipContainer); OwnershipContainer.text(" Price : "); $("<input/>").attr("type", "text").attr("name", "Ownerships[" + OwnershipsCount + "].Price").attr("id", "Ownerships[" + OwnershipsCount + "]_Price").appendTo(OwnershipContainer); var RemoveButton = $("<div/>").attr("class", "remove-ownership").text("Remove").appendTo(OwnershipContainer); //      -   RemoveButton.click(RemoveOwnership); OwnershipsCount++; }
      
      







標準のModelBinderが配列を正しく処理するためには、配列のインデックスが密接に移動する必要があります。したがって、たとえば、番号4の中間フィールドを削除する場合、その後のすべてを再カウントする必要があります。



 function RemoveOwnership() { var RecalculateStartNum = parseInt($(this).parent().attr("id").substring("OwnershipContainer".length)); //  div $(this).parent().remove(); for (var i = RecalculateStartNum+1; i < OwnershipsCount; i++) { //   name  id RecalculateNamesAndIds(i); } OwnershipsCount--; } function RecalculateNamesAndIds(number) { var prevNumber = number - 1; $("#OwnershipContainer" + number).attr("id", "OwnershipContainer" + prevNumber); // "["  "]"    id DOM-  jquery       \\ $("#Ownerships\\[" + number + "\\]_Name").attr("id", "Ownerships[" + prevNumber + "]_Name").attr("name", "Ownerships[" + prevNumber + "].Name"); $("#Ownerships\\[" + number + "\\]_Price").attr("id", "Ownerships[" + prevNumber + "]_Price").attr("name", "Ownerships[" + prevNumber + "].Price"); }
      
      







以上です。 したがって、標準のModelBinderは、名前付きフォームフィールドを正しく処理できます。



All Articles