ASP.NET MVC 3.0知識メモ(3)【主従属性共同編集後のフォーム提出】
17946 ワード
一般的に、あるエンティティを編集するのは問題ありません.例えば、マイクロソフトの公式音楽ショップでは、自動的に生成されたコードでスムーズにできます.しかし、2つのモデルを一緒に編集し、Actionに一緒に提出するビジネスシナリオがあり、問題が発生しました.たとえば、受注や受注明細などです.
一.使用する実装クラスを列挙
赤い線を太くしたエンティティは、次にマスターがエンティティから同時に編集し、同時に提出するマスター解です.
二.2つのアクションを定義します.1つはページを開くために使用され、1つはクライアントがフォームを発行する要求に応答するために使用されます. Get要求に基づくCreateOrder()はページを表示するために使用され、Viewビューレイヤを介して注文本体Orderを表示し、注文スレーブOrderDetail(Ajax非同期ロードに基づいて生成)を表示する前に、注文タイプドロップダウンボックスを初期化します.SelectListクラス: が必要です.クライアントがフォームを送信する要求に応答するために使用される:
三.従属モデルをPartialViewにする
注意が必要なのはHtmlです.BeginCollectionItem(「Order.OrderDetailList」)のパラメータ名は、OrderDetailがホーム・ページに表示されたときの名前(name)の接頭辞であるため、非常に重要です.また、この名前には中括弧のペア「[]」が含まれており、製品名ProductNameなどのGuidの値があり、クライアント名では次の可能性があります.
type="text"
value=""
name="Order.OrderDetailList[5c9f0287-82a2-41f3-96b4-9c8b2459527c].ProductName">
四.ホームフェースの設定
依存モデルOrderDetailの介入があるため、マスターモデルの名前もすべて接頭辞を付けなければならない.そうしないと、本来正常なマスターモデルでもコミットされたデータをマスターエンティティクラスに対応できない.原因は不明である.
ついでに、ドロップダウン・ボックスのバインド方法を挙げます.
五.オーダー詳細の表示
受注明細が表示される領域を計画するのは、受注の下にあるDivです.実際のプロジェクトでは、レイアウトを真剣に検討することができます.
六.「+」ボタンをクリックして新しい明細を動的にロードし、削除をサポートします.もちろん、リフレッシュはありません.
サービス側にPost形式で要求を開始し、要求が成功すると、得られた戻り値(HTML部分ブロック)が「InsertAfter」方式で追加され、UpdateTargetIdで指定された領域に更新され、最後にOnSuccessで指定されたJS関数が実行される.
七.プライマリ・モデル・フィールドは、各フィールド名に接頭辞を付ける必要があることに注意してください.
提案のデバッグ方法:火狐ブラウザのFireBugツールを採用して、IEブラウザのHttpWatchと
一.使用する実装クラスを列挙
/// <summary>
///
/// </summary>
public class Order
{
public int OrderID { set; get; }
[Display(Name = " ")]
public string Description { set; get; }
[Display(Name = " ")]
public string CreatePerson { set; get; }
[Display(Name = " ")]
public DateTime CreateDate { set; get; }
[Display(Name=" ")]
public int CategoryID { set; get; }
public List<OrderDetail> OrderDetailList { set; get; }
}
/// <summary>
///
/// </summary>
public class OrderDetail
{
public int OrderDetailID { set; get; }
public int OrderID { set; get; }
public string ProductName { set; get; }
public int Amount { set; get; }
public double UnitPrice { set; get; }
}
/// <summary>
///
/// </summary>
public class Category
{
public int CategoryID { set; get; }
public string CategoryName { set; get; }
}
赤い線を太くしたエンティティは、次にマスターがエンティティから同時に編集し、同時に提出するマスター解です.
二.2つのアクションを定義します.1つはページを開くために使用され、1つはクライアントがフォームを発行する要求に応答するために使用されます.
[HttpGet]
public ActionResult CreateOrder()
{
var CategoryItems = new List<Category>() {
new Category(){
CategoryID = 10,
CategoryName = " "
},
new Category(){
CategoryID = 11,
CategoryName = " "
}
};
ViewData["Order.CategoryID"] = new SelectList(CategoryItems, "CategoryID", "CategoryName", "");
return View();
}
[HttpPost]
public ActionResult CreateOrder(Order order)
{
order.OrderDetailList = orderDetails;
return RedirectToAction("CreateOrder");
}
三.従属モデルをPartialViewにする
@model TelerikMvcApplication1.Models.OrderDetail
@using TelerikMvcApplication1.Helpers
<div class="editorRow">
@using (Html.BeginCollectionItem("Order.OrderDetailList"))
{
@Html.LabelFor(d => d.ProductName)
@Html.TextBoxFor(d => d.ProductName)
<br />
@Html.LabelFor(d => d.Amount)
@Html.TextBoxFor(d => d.Amount)
<br />
@Html.LabelFor(d => d.UnitPrice)
@Html.TextBoxFor(d => d.UnitPrice)
<hr />
<a href="#" class="deleteRow">delete</a>
}
</div>
注意が必要なのはHtmlです.BeginCollectionItem(「Order.OrderDetailList」)のパラメータ名は、OrderDetailがホーム・ページに表示されたときの名前(name)の接頭辞であるため、非常に重要です.また、この名前には中括弧のペア「[]」が含まれており、製品名ProductNameなどのGuidの値があり、クライアント名では次の可能性があります.
type="text"
value=""
name="Order.OrderDetailList[5c9f0287-82a2-41f3-96b4-9c8b2459527c].ProductName">
四.ホームフェースの設定
依存モデルOrderDetailの介入があるため、マスターモデルの名前もすべて接頭辞を付けなければならない.そうしないと、本来正常なマスターモデルでもコミットされたデータをマスターエンティティクラスに対応できない.原因は不明である.
<label for="@string.Format("Order.{0}", "Description")"> </label>
@Html.TextBox(string.Format("Order.{0}", "Description"))
ついでに、ドロップダウン・ボックスのバインド方法を挙げます.
//Controller
var CategoryItems = new List<Category>() {
new Category(){
CategoryID = 10,
CategoryName = " "
},
new Category(){
CategoryID = 11,
CategoryName = " "
}
};
ViewData["Order.CategoryID"] = new SelectList(CategoryItems, "CategoryID", "CategoryName", "");
//View
@Html.DropDownList(string.Format("Order.{0}", "CategoryID"), @ViewData["Order.CategoryID"] as List<SelectListItem>, "-- --", new { })
五.オーダー詳細の表示
受注明細が表示される領域を計画するのは、受注の下にあるDivです.実際のプロジェクトでは、レイアウトを真剣に検討することができます.
<fieldset>
<legend> </legend>
<div id="OrderDetailDiv">
</div>
</fieldset>
六.「+」ボタンをクリックして新しい明細を動的にロードし、削除をサポートします.もちろん、リフレッシュはありません.
@using (Ajax.BeginForm("CreateOrderDetail", "Home", new AjaxOptions()
{
HttpMethod = "POST",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "OrderDetailDiv",
OnSuccess = "SuccessCallBack"
}))
{
<input type="submit" id="btnAddDetail" value=" + " />
}
サービス側にPost形式で要求を開始し、要求が成功すると、得られた戻り値(HTML部分ブロック)が「InsertAfter」方式で追加され、UpdateTargetIdで指定された領域に更新され、最後にOnSuccessで指定されたJS関数が実行される.
七.プライマリ・モデル・フィールドは、各フィールド名に接頭辞を付ける必要があることに注意してください.
@using (Html.BeginForm("CreateOrder", "Home", FormMethod.Post))
{
<input type="submit" value=" " />
<hr />
<label for="@string.Format("Order.{0}", "Description")">
</label>
@Html.TextBox(string.Format("Order.{0}", "Description"))
<br />
<br />
<label for="@string.Format("Order.{0}", "CreatePerson")">
</label>
@Html.TextBox(string.Format("Order.{0}", "CreatePerson"))
<br />
<br />
<label for="@string.Format("Order.{0}", "CreateDate")">
</label>
@Html.TextBox(string.Format("Order.{0}", "CreateDate"))
<br />
<br />
<label for="@string.Format("Order.{0}", "CategoryID")">
</label>
@Html.DropDownList(string.Format("Order.{0}", "CategoryID"), @ViewData["Order.CategoryID"] as List<SelectListItem>, "-- --", new { })
<br />
<br />
<fieldset>
<legend> </legend>
<div id="OrderDetailDiv">
</div>
</fieldset>
}
提案のデバッグ方法:火狐ブラウザのFireBugツールを採用して、IEブラウザのHttpWatchと