Reputation: 85
I'm learning ASP.NET MVC 4 using VS 2010 and Jquery 1.7.1. I'm having trouble serializing my collection back to controller. I'm using this Plugin to serialize my model to JSON object.
Here is my Controller:
public class CustomerController : Controller
{
public ActionResult Index()
{
CustomerViewModel model = new CustomerViewModel();
model.Orders = GetOrders().ToList();
return View(model);
}
[HttpPost]
public ActionResult Save(CustomerViewModel model)
{
if (ModelState.IsValid)
{
}
return View(model);
}
private IEnumerable<Order> GetOrders()
{
List<Order> orders = new List<Order>();
orders.Add(new Order() { OrderID = 1, CustomerID = 1, TotalAmount = 100.99M, OrderName = "Order1", Discount = 5.00M, TotalItems = 5, OrderDate = DateTime.Now });
orders.Add(new Order() { OrderID = 2, CustomerID = 1, TotalAmount = 101.99M, OrderName = "Order2", Discount = 6.00M, TotalItems = 6, OrderDate = DateTime.Now });
orders.Add(new Order() { OrderID = 3, CustomerID = 1, TotalAmount = 102.99M, OrderName = "Order3", Discount = 6.00M, TotalItems = 7, OrderDate = DateTime.Now });
orders.Add(new Order() { OrderID = 4, CustomerID = 1, TotalAmount = 103.99M, OrderName = "Order4", Discount = 7.00M, TotalItems = 8, OrderDate = DateTime.Now });
orders.Add(new Order() { OrderID = 5, CustomerID = 1, TotalAmount = 104.99M, OrderName = "Order5", Discount = 8.00M, TotalItems = 9, OrderDate = DateTime.Now });
orders.Add(new Order() { OrderID = 6, CustomerID = 1, TotalAmount = 105.99M, OrderName = "Order6", Discount = 9.00M, TotalItems = 10, OrderDate = DateTime.Now });
return orders;
}
}
View:
<div>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Customer Details</legend>
<table>
<tr>
<td>
<%: Html.LabelFor(m=>m.Customer.FirstName) %>
</td>
<td>
<%: Html.TextBoxFor(m=>m.Customer.FirstName) %>
</td>
</tr>
<tr>
<td>
<%: Html.LabelFor(m=>m.Customer.LastName) %>
</td>
<td>
<%: Html.TextBoxFor(m=>m.Customer.LastName) %>
</td>
</tr>
<tr>
<td>
<%: Html.LabelFor(m=>m.Customer.EmailAddress) %>
</td>
<td>
<%: Html.TextBoxFor(m => m.Customer.EmailAddress)%>
</td>
</tr>
<tr>
<td>
<%: Html.LabelFor(m=>m.Customer.PhoneNumber) %>
</td>
<td>
<%: Html.TextBoxFor(m => m.Customer.PhoneNumber)%>
</td>
</tr>
</table>
<table id="tblOrdersGrid">
<tr>
<th>
OrderID
</th>
<th>
Order Name
</th>
<th>
Total Amount
</th>
<th>
Total Items
</th>
</tr>
<% foreach (DemoHtmlHelpers.Models.Order order in Model.Orders)
{%>
<tr>
<td id="tdOrderID">
<%: order.OrderID%>
</td>
<td id="tdOrderName">
<%: order.OrderName%>
</td>
<td id="tdTotalAmount">
<%: order.TotalAmount%>
</td>
<td id="tdTotalItems">
<%: order.TotalItems%>
</td>
</tr>
<%} %>
</table>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
</div>
<script type="text/javascript">
$(function () {
$('form').submit(function (e) {
var customerViewModel = $(this).serializeObject();
var allOrders = new Array();
var order = null;
var orderRows = $('#tblOrdersGrid').find('tr').not(':first');
$.each(orderRows, function (i, orderItem) {
order = new Object();
order.OrderID = $(orderItem).find('#tdOrderID').text();
order.OrderName = $(orderItem).find('#tdOrderName').text();
order.TotalAmount = $(orderItem).find('#tdTotalAmount').text();
order.TotalItems = $(orderItem).find('#tdTotalItems').text();
allOrders.push(order);
});
customerViewModel.Orders = allOrders;
//customerViewModel['Orders'] = allOrders;
$.post('<%= Url.Action("Save", "Customer") %>', customerViewModel, function (data) {
alert('Successfully saved.');
});
return false;
});
});
</script>
Model Classes:
[Serializable]
public class Customer
{
public Customer()
{
this.CreatedDate = DateTime.Now;
}
public int CustomerID { set; get; }
[Required(AllowEmptyStrings = false)]
public string FirstName { set; get; }
[Required(AllowEmptyStrings = false)]
public string LastName { set; get; }
[Required(AllowEmptyStrings = false)]
public string PhoneNumber { set; get; }
[Required(AllowEmptyStrings = false)]
public string EmailAddress { set; get; }
[DataType(DataType.Date)]
public DateTime CreatedDate { set; get; }
}
[Serializable]
public class Order
{
public Order()
{
this.OrderDate = DateTime.Now;
}
public int OrderID { set; get; }
public int CustomerID { set; get; }
[Required(AllowEmptyStrings = false)]
public string OrderName { set; get; }
[Required()]
public decimal TotalAmount { set; get; }
[DataType(DataType.Date)]
public DateTime OrderDate { set; get; }
public decimal Discount { set; get; }
public decimal TotalItems { set; get; }
}
[Serializable]
public class CustomerViewModel
{
public CustomerViewModel()
{
this.Customer = new Customer();
this.Orders = new List<Order>();
}
public Customer Customer { get; set; }
public List<Order> Orders { get; set; }
}
I can get the customer object back to controller but somehow my order collection is not binding back. Please refer to the screen shots below:
Any clue will be appreciated.
Update 1:
Upvotes: 2
Views: 6288
Reputation: 54618
Check out Convert form data to JS object with jQuery. Once you have a nice JS Object, you can add whatever you want. Once you are ready you simply Post the Json to Asp.Net mvc.
var customerViewModel = $(this).ToJson(); // or whatever you call this function
customViewModel.Orders = [];
var orderRows = $('#tblOrdersGrid').find('tr').not(':first');
$.each(orderRows, function (i, orderItem) {
order = {};
order.OrderID = $(orderItem).find('#tdOrderID').text();
order.OrderName = $(orderItem).find('#tdOrderName').text();
order.TotalAmount = $(orderItem).find('#tdTotalAmount').text();
order.TotalItems = $(orderItem).find('#tdTotalItems').text();
customViewModel.Orders.push(order);
});
Then...
$.post('<%= Url.Action("Save", "Customer") %>',
JSON.stringify(customerViewModel),
function (data) {
alert('Successfully saved.');
});
Upvotes: 1