首页 > 解决方案 > 如何用视图模型和表格内容序列化表单?

问题描述

我是 ASP.NET MVC 的新手。我面临一个问题,无法找到解决方案。实际上我正在创建一个库存管理项目。在这个项目中,我有 2 个 ViewModel。一个是 PurchaseOrderViewModel,另一个是 TableViewModel。现在我在弹出模式中使用两者并将详细信息保存在视图模型中,但我无法做到这一点。在图像中,您可以看到下面显示了一个表记录,我需要将其插入到视图模型中。请帮助我。我真的很感谢你。

        [HttpPost]
    public async Task<ActionResult> CreateOrUpdatePurchase(PurchaseOrderViewModel purchase)
    {
        PurchaseOrder purchase2 = new PurchaseOrder();
        int suplierId = purchase.Supplier_ID;
        purchase.Supplier_ID = suplierId;
        purchase.SupplierName = context.Suppliers.Where(x => x.Supplier_ID == suplierId).Select(x => x.Supplier_Name).FirstOrDefault();
        string loginId = Convert.ToString(Session["LoginId"]);
        string UserRoleName = Convert.ToString(Session["UserTypeName"]);
        try
        {
            if (!string.IsNullOrEmpty(loginId))
            {
                if (UserRoleName == RoleTypeConstant.CustomerUserType)
                {
                    PurchaseOrder purchase1 = new PurchaseOrder();
                    purchase1.LoginID = loginId;
                    purchase1.PurchaseID = purchase.PurchaseID;
                    purchase1.SupplierID = purchase.Supplier_ID;
                    purchase1.SupplierName = purchase.SupplierName;
                    purchase1.Currency = purchase.Currency;
                    purchase1.Date_Of_Purchase = purchase.Date_Of_Purchase;
                    purchase1.Due_Date = purchase.Due_Date;
                    purchase1.CreatedBy = loginId;
                    purchase1.CreatedOn = DateTime.Now;
                    purchase1.UpdatedBy = loginId;
                    purchase1.UpdatedOn = DateTime.Now;
                    purchase1.Status = StatusConstant.Active;
                    bool regCustBen = await _websiteRepo.AddPurchase(purchase1);
                    if (regCustBen)
                    {
                        return Json(new { success = true, message = "Saved Successfully" }, JsonRequestBehavior.AllowGet);
                    }
                    return RedirectToAction("GetPurchasePartial");
                }
                else
                {
                    return RedirectToAction("Purchase_Order", "Home");
                }
            }
            else
            {
                return RedirectToAction("Login", "Account");
            }
        }
        catch (Exception)
        {
            throw;
        }
    }


public class TableViewModel 
{

    public int Pid { get; set; }
    //public string ProductName { get; set; }
    public string Qty { get; set; }
    public string Price { get; set; }
    public string Amount { get; set; }

}

public class PurchaseOrderViewModel
{
    public int PurchaseID { get; set; }
    public string LoginID { get; set; }

    public int SupplierID { get; set; }
    public int Supplier_ID { get; set; }

    public string SupplierName { get; set; }
    public string Supplier_Name { get; set; }

    public string Currency { get; set; }

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    public string Date_Of_Purchase { get; set; }

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    public string Due_Date { get; set; }

    public string CreatedBy { get; set; }

    public DateTime? CreatedOn { get; set; }

    public string UpdatedBy { get; set; }

    public DateTime? UpdatedOn { get; set; }
    public int? Status { get; set; }

    public int OrderID { get; set; }

    public string ProductName { get; set; }

    //public List<Order> s { get; set; }

    public int Stock_ID { get; set; }
    public string Stock_Name { get; set; }

    public string Quantity { get; set; }

    public decimal Price { get; set; }

    public decimal Amount { get; set; }

    public List<TableViewModel> TableListDto  { get; set; }
}

我的脚本是

    function CreateOrUpdate() {
        debugger;
        var modal = $("#purchaseModal");
        var form = $('form[name="purchaseForm"]');

        let tableData = $('#detailsTable > tbody > tr');
        debugger;
        console.log(tableData);

        var tableDto = [];

        $.each(tableData, function (rindex, row) {
            console.log(row);

            let tmp = {};

            tmp.pid = $(row).find('td:nth-child(1)').attr('pid');
            //tmp.productName = $(row).find('td:nth-child(1)').text();
            tmp.qty = $(row).find('td:nth-child(2)').text();
            tmp.price = $(row).find('td:nth-child(3)').text();
            tmp.amount = $(row).find('td:nth-child(4)').text();

            tableDto.push(tmp);
            tmp = {};
        });



        form.validate();
        if (!form.valid()) {
            return;
        }
        else {
            var data = form.serialize();
            //data.TableListDto = tableDto.serialize();
            $.post("/Home/CreateOrUpdatePurchase", data, function (res) {
                if (res) {
                    modal.modal('hide');
                    dataTable.ajax.reload();
                    $.notify("Saved Successfully", {
                        className: "success",
                        globalPosition: 'top - center'
                    });
                }
            })
        }
    }

让我向您展示我的输出屏幕。点击这里

标签: javascriptc#jqueryasp.net-mvcdatatables

解决方案


您将想要发布您的购买清单,这有点捏造和人为的示例,但应该向您展示 c# 中的基本移植和savePurchases命名空间中函数的核心保存部分。我写得很快,并且没有测试过去非常基本的(也没有 c# 测试)所以可能有一些错别字等。

为此,您只需要注意两件事

  1. 要保存的模型(这些列表)
  2. 发送到该保存购物车方法的对象(与该方法匹配的数组)查看savePurchases函数

我制作了一个可以使用的表单,将物品放入购物车(没有添加删除),购物车是purchases命名空间中的对象数组。这只有简单的“添加项目”,其中没有超级花哨的东西。

[HttpPost]
public async Task<JsonResult> CreateOrUpdatePurchase(List<SaveModel> purchase)
{
    // first validate your data here
    // second, call your middle ware code to update database
    // third return results back, whatever you need, I made this up
    return Json(
         new PurchaseResultModel
         {
              PurchaseQuantity = somevalue,
              PurchaseValue = somemoney,
              /*These are Provider only options.*/
              SavedOK = true, //verify save OK
              ValidData = true // validated data OK
          });
 }
public class SaveModel 
{
    public int Pid { get; set; }
    public string Qty { get; set; }
}

创建一些 JSON 以发回

var myApp = {
  products: [{
    pid: "123",
    name: "Water Cats",
    price: 42.34
  }, {
    pid: "32234",
    name: "Bolts",
    price: 1.18
  }, {
    pid: "56",
    name: "Sheep",
    price: 34.34
  }, {
    pid: "2323",
    name: "Sack - cotton",
    price: 5.99
  }],
  currency: 'USD',
  currencySymbol: '$',
  onAddProduct: function() {
    let productCart = $('#product-cart');
    let firstProductItem = productCart
      .find('.product-item')
      .first();

  },
  prod: {},
  savePurchases: function(event) {
    let me = event.data[0].arg1;
    if (me.purchases.length > 0) {
      // get what we sold
      let purchases = [];
      // this just to show how to make a match to the c# class
      // I left out price and amount since that should be a server calculation to prevent hacking of values.
      for (var i = 0; i < me.purchases.length; i++) {
        let p = {
          Pid: me.purchases[i].pid,
          Qty: me.purchases[i].qty
        };
        purchases.push(p);
      }

      $.ajax({
          url: "/Home/SavePurchase",
          data: purchases,
        })
        .complete(function(res) {
          if (res) {
            modal.modal('hide');
            dataTable.ajax.reload();
            $.notify("Saved Successfully", {
              className: "success",
              globalPosition: 'top - center'
            });
          }
        })
        .fail(function(x) {
          // save fail action
        });
    } else {
      // tell them they made no selections?
    }
  },
  validate: function() {
    form.validate();
    if (!form.valid()) {
      return;
    } else {
      //do valid thing
    }
  },
  onQuantityChange: function(event) {
    let me = event.data[0].arg1;
    if (this.value > 0) {
      let opt = me.productSelect.find("option:selected");
      let product = opt.data('item');
      $('#price').val(product.price);
      let a = me.roundToCents(product.price * $(this).val());
      me.setFieldAmount(a, $('#amount-sold')[0]);
    } else {
      $('#price').val(0);
      me.setFieldAmount(0, $('#amount-sold')[0]);
    }
  },
  localStringToNumber: function(s) {
    return Number(String(s).replace(/[^0-9.-]+/g, ""));
  },
  setFieldAmount: function(amount, field) {
    var options = {
      maximumFractionDigits: 2,
      currency: this.currency,
      style: "currency",
      currencyDisplay: "symbol"
    };
    field.value = amount ?
      this.localStringToNumber(amount).toLocaleString(undefined, options) :
      '';
  },
  setTextAmount: function(amount, field) {
    var options = {
      maximumFractionDigits: 2,
      currency: this.currency,
      style: "currency",
      currencyDisplay: "symbol"
    };
    let v =
      amount ?
      this.localStringToNumber(amount).toLocaleString(undefined, options) :
      '';
    field.text(v);
  },
  onProductChange: function(event) {
    let me = event.data[0].arg1;
    let opt = me.productSelect.find("option:selected");
    let hasSelection = !!opt;
    me.productSelect.toggleClass('choice-made', hasSelection);
    let q = $('#quantity');
    q.prop('disabled', !hasSelection)
      .val(hasSelection ? 1 : 0)
      .trigger('change');
  },
  roundToCents: function(num) {
    return Math.round(num * 100) / 100;
  },
  onAddItem: function(event) {
    let me = event.data[0].arg1;
    let prod = me.productSelect;
    // only if we made a valid choice
    if (prod.hasClass('choice-made')) {
      let optVal = prod.find("option:selected").val();
      let product = me.products.find(x => x.pid === optVal);
      if (product) {
        let q = $('#quantity');
        let cart = $('#product-cart');
        let first = cart.find('.product-item').first();
        let itemRowC = first.clone();
        itemRowC.find('.product-name').text(product.name);
        itemRowC.find('.product-quantity').text(q.val());
        me.setTextAmount(product.price, itemRowC.find('.product-price').first());
        me.setTextAmount($('#amount-sold').val(), itemRowC.find('.product-amount').first());
        let v = {
          pid: optVal,
          qty: q.val()
        };
        me.purchases.push(v);
        itemRowC.find('.hidden').find('div').unwrap('.hidden');
        let calctot = cart.find('.grand-total-group');
        itemRowC.insertBefore(calctot);
        let total = me.getCalculatedTotal(me.purchases);
        // reset quantity values
        q.prop('disabled', true)
          .val(0)
          .trigger('change');
        prod.val('')
          .removeClass('choice-made');
      }
    }
  },
  getCalculatedTotal: function(purchases) {
    let total = 0;
    let count = purchases.length;
    for (var i = 0; i < purchases.length; i++) {
      let product = this.products.find(x => x.pid === purchases[i].pid);
      total = total + (product.price * purchases[i].qty);
    }
    $('.products-in-cart').text(count);
    this.setTextAmount(total, $('#grand-total'));
    return total;
  },
  startup: function() {
    this.productSelect = $('#products');
    this.purchases = [];
    //add products
    this.products.forEach(product => {
      const opt = $('<option value="' + product.pid + '">' + product.name + '</option>');
      opt.data('item', product);
      this.productSelect.append(opt);
    });
    $('#quantity').on('change', [{
      arg1: this
    }], this.onQuantityChange);
    $('#products').on('change', [{
      arg1: this
    }], this.onProductChange);
    $('#add-to-cart').on('click', [{
      arg1: this
    }], this.onAddItem);
    $('#save-cart').on('click', [{
      arg1: this
    }], this.savePurchases);
  }
};

myApp.startup();
.hidden {
  display: none;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

<div id="purchaseModal">
  <div id="purchaseOptions" data-list="[]" class="container-fluid">
    <div class="row">
      <div class="col-md-4 order-md-2 mb-4">
        <h4 class="d-flex justify-content-between align-items-center mb-3">
          <span class="text-muted">Your cart</span>
          <span class="products-in-cart badge badge-secondary badge-pill">3</span>
        </h4>
        <ul id="product-cart" class="list-group mb-3">
          <li class="list-group-item d-flex justify-content-between lh-condensed product-item">
            <div class="hidden">
              <div>
                <h6 class="my-0">Product name</h6>
                <small class="text-muted product-name">Brief description</small>
              </div>
              <div>
                <h6 class="my-0">Quantity</h6>
                <small class="text-muted product-quantity">3</small>
              </div>
              <div>
                <h6 class="my-0">Price</h6>
                <small class="text-muted product-price">$12.24</small>
              </div>
              <div>
                <h6 class="my-0">Amount</h6>
                <small class="centered-text text-muted product-amount">$36.72</small>
              </div>
            </div>
          </li>
          <li class="grand-total-group list-group-item d-flex justify-content-between bg-light">
            <div class="text-success">
              <span>Total (USD)</span>
            </div>
            <strong class="text-success"><span id="grand-total">0</span></strong>

          </li>
        </ul>
      </div>
      <div class="col-md-12 order-md-1">
        <h4 class="mb-3">Choose Products</h4>
        <form class="product-choice needs-validation" novalidate="" _lpchecked="1">
          <div class="row">
            <div class="col-md-5 mb-3">
              <label for="products">Products</label>
              <select class="custom-select d-block w-100" id="products" required="">
                <option value="">Choose...</option>
              </select>
              <div class="invalid-feedback">
                Please select a valid Product.
              </div>
            </div>
          </div>
          <div class="row ">
            <div class="col-3 ">
              <label for="quantity">Quantity</label>
              <div class="input-group">
                <div class="input-group-prepend">
                  <span class="input-group-text">#</span>
                </div>
                <input type="number" disabled="true" class="form-control" id="quantity" placeholder="0" required="">
                <div class="invalid-feedback" style="width: 100%;">
                  Quantity is required.
                </div>
              </div>
            </div>
            <div class="col-3 ">
              <label for="price">Price</label>
              <div class="input-group">
                <div class="input-group-prepend">
                  <span class="input-group-text">$</span>
                </div>
                <input type="text" class="form-control" id="price" disabled="true">
              </div>
            </div>
            <div class="col-3 ">
              <label for="amount-sold">Amount</label>
              <div class="input-group">
                <div class="input-group-prepend">
                  <span class="input-group-text">$</span>
                </div>
                <input type="text" pattern="^\d+(?:\.\d{1,2})?$" class="form-control" id="amount-sold" disabled="true">
              </div>
            </div>
          </div>
          <div class="col-3 ">
            <button id="add-to-cart" class="form-control btn btn-info btn-sm " type="button">Add to Cart</button>
          </div>
      </div>
      <hr class="sm-4">
      <button id="save-cart" class="btn btn-primary btn-md btn-block" type="button">Save Cart</button>
      </form>
    </div>
  </div>
</div>
</div>


推荐阅读