【问题标题】:Serialize form object and collections with ASP.NET MVC Jquery Ajax使用 ASP.NET MVC Jquery Ajax 序列化表单对象和集合
【发布时间】:2014-06-13 15:37:30
【问题描述】:

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

这是我的控制器:

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

}

我可以将客户对象返回给控制器,但不知何故我的订单集合没有绑定回来。请参考以下屏幕截图:

任何线索将不胜感激。

更新 1:

【问题讨论】:

  • 我 99% 确定您不能 serialize() 表单然后附加订单。如果您查看了 http 请求(在 Chrome->Dev Tools(F12)、Network Tab、Filter、XHR 中),我敢打赌该请求是 Form-Url-Encoded 并且不正确。如果您可以发布其中一个请求,则更容易发现不正确的地方。
  • @Erik 感谢您的有用提示。我已经用请求更新了我的问题。正如您所说,http 请求是 Form-Url-Encoded 那么我怎样才能发回我的表单数据?

标签: jquery serialization model-view-controller


【解决方案1】:

查看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.');
});

【讨论】:

  • 再次感谢您的回复。我知道我可以通过指定所有必需的参数来使用 $.ajax({}) 发布任何对象,但我试图避免任何我必须通过收集每个属性的值来手动构建对象的情况。我正在使用 serializeObject() 一次收集表单中的所有字段值,然后添加对象集合(在本例中为 Orders)。有什么办法可以做到这一点?
  • 没有自动的方法采用这种形式并将其转换为json,然后添加这些未知的其他字段。第一个链接适用于任何形式,因此不要调用 Serialize() 来调用它,并通过调用 stringify() 的唯一额外步骤来执行您当前正在执行的操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 2021-12-22
相关资源
最近更新 更多