2014-06-13 81 views
1

我正在学习使用VS 2010和Jquery 1.7.1的ASP.NET MVC 4。我无法序列化我的收藏回控制器。 我正在使用此Plugin将我的模型序列化为JSON对象。使用ASP.NET MVC序列化表单对象和集合Jquery Ajax

这里是我的控制器:

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; 

    } 

} 

查看:

<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> 

模型类:

[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; } 

} 

我能得到客户对象返回给控制器,但不知我的指令集是没有约束力。请参考下面的屏幕截图:

Bind the customer object

Does not bind the orders list

任何线索将不胜感激。

更新1:

Request in google chrome

+0

我99%肯定你不能'连载()'形式然后追加订单。如果你看看http请求(在Chrome->开发工具(F12),网络选项卡,过滤器,XHR)我打赌请求是一个Form-Url编码,这是不正确的。如果您可以发布其中一项请求,则可以更轻松地查看哪些内容不正确。 –

+0

@Erik感谢您的有用提示。我已经用请求更新了我的问题。正如你所说,http请求是Form-Url-Encoded,所以我怎样才能发回我的表单数据? – TJP

+0

检查此文章:https://stackoverflow.com/questions/15317856/asp-net-mvc-posting-json/15318612#15318612 –

回答

0

退房Convert form data to JS object with jQuery。一旦你有一个不错的JS对象,你可以添加任何你想要的。一旦你准备好了,你只需要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); 
}); 

则...

$.post('<%= Url.Action("Save", "Customer") %>', 
    JSON.stringify(customerViewModel), 
    function (data) { 
    alert('Successfully saved.'); 
}); 
+0

再次感谢您的答复。我知道我可以通过指定所有必需的参数使用$ .ajax({})发布任何对象,但我试图避免任何必须通过为每个属性收集值手动构建对象的情况。我使用serializeObject()一次收集表单中的所有字段值,然后添加一个对象集合(在本例中为Orders)。有什么办法可以做到这一点? – TJP

+0

有没有自动的方式*采取这种形式,并将其转换为json然后添加这些未知*的其他领域。第一个链接适用于任何形式,所以不要使用'Serialize()'来调用它,而只需调用'stringify()'的额外步骤即可完成目前的工作。 –