Home MVC 4 Detail Records Won't Bind

# MVC 4 Detail Records Won't Bind

Eric Schilling
1#
Eric Schilling Published in 2017-12-04 23:56:12Z
 I am stuck with a master/detail type of problem in my "CreateOrder" view. The customer has specified that they want a specific set of detail records based on the selection from a dropdown. Based on the selection, 2, 3 or 4 detail records will be displayed for the user to enter information. The user fills out the entire form with both information in the "master" part and the details part. When they are done, they click the "Create" button. The problem is, the only data that gets to the controller is the "master" part. I know I may be giving out too much info but this is pared down from the actual app. I'm not sure what is necessary to solve the problem so I am posting everything. Let's start with the models... public class Order { public int OrderID { get; set; } public string CustomerName { get; set; } public DateTime OrderDate { get; set; } public DateTime RequiredBy { get; set; } public string OrderStatus { get; set; } } public class OrderDetails { public int OrderDetailID { get; set; } public int OrderID { get; set; } public string ItemName { get; set; } public int ItemQty { get; set; } public int UnitCost { get; set; } } public class MyDDL { public int ID { get; set; } public string Name { get; set; } } public class MyViewModel { public Order Order_Info { get; set; } public int SelectedRowCount { get; set; } public IList OrderItems { get; set; } }  So the models are pretty straightforward and they mimic the examples I have seen here and elsewhere. My ViewModel combines the Order model, the selected value of the DDL and a list of OrderDetail objects. Here is the Controller: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MasterDetailBindingProblem.Models; namespace MasterDetailBindingProblem.Controllers { public class OrdersController : Controller { public ActionResult OrdersIndex() { List currentOL = new List(); return View(currentOL); } [HttpGet] public ActionResult OrdersCreate() { //Set defaults for create view. MyViewModel currentVM = new MyViewModel(); Order currentOrder = new Order(); List currentItems = new List(); currentVM.Order_Info = currentOrder; currentVM.OrderItems = currentItems; return View(currentVM); } [HttpPost] public ActionResult OrdersCreate(MyViewModel currentVM) { //When ready to run, set breakpoint online checking ModelState. When the code //gets there, check the currentVM. That part of the model will be null. Even if //you put data in the rows, it will still be null. if (ModelState.IsValid) { //Code here to do stuff before saving to database. //The problem is that the OrderItems part of the model is null //because for some reason it doesn't bind. return RedirectToAction("OrdersIndex"); } return View(); } public ActionResult GetItemsPartial(string id) { //Create a list of id items. int rowCount = Convert.ToInt32(id); List orderDetailList = new List(); //Create the correct number of empty layers. for (int i = 0; i < rowCount; i++) { OrderDetails curItem = new OrderDetails(); orderDetailList.Add(curItem); } return PartialView("_OrderDetailsPartial", orderDetailList); } } }  If you set a breakpoint at the beginning of the HttpPost for OrdersCreate and look at currentVM, you will note the the OrderDetails attribute is null. It should have the data you just entered but it doesn't. Here is the Partial view Razor code: @model IList
@if (Model.Any()) { for (int i = 0; i < Model.Count(); i++) { var item = Model[i];
ItemID WorkOrderID ItemName ItemQTY UnitCost
@Html.DisplayFor(m => m[i].OrderDetailID) @Html.ValidationMessageFor(m => m[i].OrderDetailID)
@Html.EditorFor(m => m[i].OrderID) @Html.ValidationMessageFor(m => m[i].OrderID)
@Html.EditorFor(m => m[i].ItemName) @Html.ValidationMessageFor(m => m[i].ItemName)
@Html.EditorFor(m => m[i].ItemQty) @Html.ValidationMessageFor(m => m[i].ItemQty)
@Html.EditorFor(m => m[i].UnitCost) @Html.ValidationMessageFor(m => m[i].UnitCost)
} } else {

Please select an option to see layers.

}  And here is the CreateOrder view: @model MasterDetailBindingProblem.Models.MyViewModel @{ ViewBag.Title = "OrdersCreate"; }

OrdersCreate

@using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true)
Create Order
@Html.LabelFor(model => model.Order_Info.OrderID)
@Html.EditorFor(model => model.Order_Info.OrderID) @Html.ValidationMessageFor(model => model.Order_Info.OrderID)
@Html.LabelFor(model => model.Order_Info.CustomerName)
@Html.EditorFor(model => model.Order_Info.CustomerName) @Html.ValidationMessageFor(model => model.Order_Info.CustomerName)
@Html.LabelFor(model => model.Order_Info.OrderDate)
@Html.EditorFor(model => model.Order_Info.OrderDate) @Html.ValidationMessageFor(model => model.Order_Info.OrderDate)
@Html.LabelFor(model => model.Order_Info.RequiredBy)
@Html.EditorFor(model => model.Order_Info.RequiredBy) @Html.ValidationMessageFor(model => model.Order_Info.RequiredBy)
@Html.LabelFor(model => model.SelectedRowCount)
@*@Html.DropDownListFor(model => model.SelectedRowCount, new SelectList(ViewBag.JointTypesDDL, "Value", "Text"),"", new { @class = "dropdown1" }) @Html.ValidationMessageFor(model => model.LCTID)*@
@Html.Partial("_OrderDetailsPartial", Model.OrderItems)

}
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }  Questions I Have Been Asked Alot Where's the database? I didn't include a database because you really don't need one to see where the code is broken. It breaks right before the data would get saved. What's the input that causes the problem? It seems not to matter. What Environment was this done in? I am using Visual Studio 2012 and MVC4 Why aren't you passing the whole model to the Ajax call? Two reasons. One, it seemed to intuitively defeat the purpose of using a partial view. Two, several examples didn't do it. Summary: I have looked at a ton of examples over the last 3 weeks. Some here, some elsewhere. I may well have missed the perfect example. If I did, I am sorry. From what I learned from all of them, I think the problem lies with how I am generating the HTML in the partial view. Something about that markup is preventing the binder from working. But I could be way off. What I am hoping is that someone can take this and tell me what I am doing wrong and SHOW me what I need to do to fix it. Thank you for taking the time to read this far. If you need more info, I will post it as soon as I can.