2

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:

Bind the customer object

Does not bind the orders list

Any clue will be appreciated.

Update 1:

Request in google chrome

3
  • I'm 99% sure you can't serialize() a form then append orders. If you took a look at the http request (in Chrome->Dev Tools(F12), Network Tab, Filter, XHR) I'm betting the request is a Form-Url-Encoded and it's incorrect. If you could post one of those requests, it's much easier to see what is incorrect. Commented Jun 13, 2014 at 16:08
  • @Erik Thanks for the useful hint. I've updated my question with request. As you were saying, the http request is Form-Url-Encoded so how can I send back my form data ? Commented Jun 13, 2014 at 18:02
  • check this article: stackoverflow.com/questions/15317856/asp-net-mvc-posting-json/… Commented Jan 11, 2018 at 16:55

1 Answer 1

1

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.');
});
Sign up to request clarification or add additional context in comments.

2 Comments

thanks again for your reply. I know I can post any object using $.ajax({}) by specifying all the required parameters but I'm trying to avoid any situation where I have to manually build an object by collecting value for each property. I'm using serializeObject() to collect all field values in a form at once and then add a collection of objects(in this case, Orders). Is there any way to achieve this ?
There is no automatic way to take this form and convert it to json then add these other fields that are unknown. The first link works with any form, so instead of Serialize() call it and do exactly what you are currently doing with the only additional step of calling stringify().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.