如何用视图模型和表格内容序列化表单?
Posted
技术标签:
【中文标题】如何用视图模型和表格内容序列化表单?【英文标题】:How to serialize form with viewmodel and table content? 【发布时间】:2020-11-06 13:28:47 【问题描述】:我是 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'
);
)
让我向您展示我的输出屏幕。 Click Here
【问题讨论】:
不要使用nth-child(1)
类型的东西,给 td
一个类以供使用 - 例如,您可以移动列而不必重做逻辑。
在您的方法中使用 purchase
之前验证它
purchase.Supplier_ID = suplierId;
?为什么?混淆Supplier_ID
和SupplierID
对我来说毫无意义
嗨,马克,如果我删除了第 n 个孩子(1),那么我怎样才能得到表中的值。你能为我提供正确的代码吗?请查看我刚刚在帖子中上传的输出屏幕。
标记,用于来自供应商表的下拉值,以保存视图模型中的值。
【参考方案1】:
您将要发布您的购买清单,这有点捏造和人为的示例,但应该向您展示 c# 中的基本移植和命名空间中savePurchases
函数中的核心保存部分。我写得很快,并且没有测试过这个非常基本的(也没有 c# 测试),所以可能有一些错别字等。
为此你只需要注意两件事
-
要保存的模型(这些列表)
发送到该保存车方法的对象(与该方法匹配的数组)参见
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+(?:\.\d1,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>
【讨论】:
非常感谢。现在我得到了如何做到这一点的答案。非常感谢!!!!以上是关于如何用视图模型和表格内容序列化表单?的主要内容,如果未能解决你的问题,请参考以下文章