从 ajax 回发到控制器操作不起作用?
Postback to controller action from ajax not working?
这是我的 ajax 电话:
$('#SaveItemButton').click(function () {
var tableData = { 'ItemViewModel': table.$('input, select').serialize() }; // here the data gets returned
//Add Data Function
function Add() {
$.ajax({
url: "/Item/Add",
data: tableData,
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (result) {
alert("success: " + result);
},
error: function (errormessage) {
alert("error: " + errormessage);
}
});
}
} );
这是我的控制器操作:
public JsonResult Add(List<ItemViewModel> ItemViewModel)
{
var x = ItemViewModel;
return Json(1, JsonRequestBehavior.AllowGet);
}
tableData返回的实际数据:
“ItemType=Type1&Unit=select&Quantity=12&Price=1000&Total=&ItemType=Type2&Unit=//select&Quantity=11&Price=2000&Total="
我的控制器操作正在接收 ItemViewModel = null。谁能告诉我我需要如何处理收到的数据,以便我可以成功回发到服务器并绑定到模型:
public class ItemViewModel
{
public int Id { get; set; }
public string ItemType { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public ICollection<ProductViewModel> Products { get; set; }
public ICollection<ServiceViewModel> Services { get; set; }
public ICollection<CustomerViewModel> Customers { get; set; }
public InvoiceViewModel Invoice { get; set; }
public string ApplicationUserID { get; set; }
public int ProductId { get; set; }
public int ServiceId { get; set; }
public int InvoiceId { get; set; }
public int CustomerId { get; set; }
public string InvoiceDate { get; set; }
public string TransferDate { get; set; }
public string TransferPlace { get; set; }
public string InvoiceDescription { get; set; }
}
这是我的观点:
@using (Html.BeginForm("Add", "Item", FormMethod.Post, new { @class = "form-horizontal", id = "ItemForm", role = "form" }))
{
<body>
<h2>Invoice</h2>
<table id="ItemTable" class="table table-hover table-secondary" style="width:100%">
<thead>
<tr>
<th></th>
<th>ItemType</th>
<th>Unit</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
<th></th>
</tr>
</thead>
</table>
</body>
}
这是 jquery 数据表,javascript:
$(document).ready(function () {
var table = $('#ItemTable').DataTable({
"dom": '<"toolbar">frtip',
"paging": true,
"pagingType": "full_numbers",
"searching": false,
responsive: {
details: {
type: 'column'
}
},
columnDefs: [{
className: 'control',
orderable: false,
targets: 0
}],
order: [1, 'asc']
});
$("div.toolbar").html(
'<button id="addRow" type="button" class="btn btn-outline-info fa fa-plus"> Add</button> <div class="divider"/>' +
'<button id="SaveItemButton" type="submit" class="btn btn-outline-secondary fa fa-save"> Save</button> <div class="divider"/>' +
'<button id="PreviewButton" type="button" class="btn btn-outline-info fa fa-eye"> Preview</button> <div class="divider"/>' +
'<button id="PrintButton" type="button" class="btn btn-info fa fa-print"> Print</button> <div class="divider"/>' +
'<button id="SendButton" type="button" class="btn btn-lump-sum fa fa-envelope"> Send</button> <div class="divider"/>' +
'<button id="DeleteButton" type="button" class="btn btn-secondary fa fa-trash"> Delete </button> <div class="divider"/>'
);
var counter = 1;
$('#addRow').on('click', function () {
table.row.add([
'',
'<input name="ItemType" class="form-control" type="text">',
'<select name="Unit" class="form-control defaultpicker">' +
'<option value="select">dan</option>' +
'<option value="select">Komad</option>' +
'<option value="select">Sat</option>' +
'<option value="select">m</option>' +
'<option value="select">m2</option>' +
'<option value="select">m3</option>' +
'<option value="select">kg</option>' +
'<option value="select">lit</option>' +
'<option value="select">pak</option>' +
'<option value="select">reč</option>' +
'</select > ',
'<input name="Quantity" class="form-control" type="number">',
'<input name="Price" class="form-control" type="text">',
'<input name="Total" class="form-control" type="text" readonly>',
'<button type="button" Id="DeleteButton" class="fa fa-times select-row btn btn-secondary btn-sm" data-id=""></button>',
]).draw(false);
counter++;
$('#ItemTable').dataTable().fnPageChange('last');
});
$('#ItemTable').on("click", "#DeleteButton", function () {
var table = $('#ItemTable').DataTable();
var row;
console.log($(this).closest('table'));
if ($(this).closest('table').hasClass("collapsed")) {
var child = $(this).parents("tr.child");
row = $(child).prevAll(".parent");
} else {
row = $(this).parents('tr');
}
table.row(row).remove().draw();
});
// Automatically add a first row of data
$('#addRow').click();
$('#SaveItemButton').click(function () {
debugger;
//Add Data Function
function Add() {
$.ajax({
url: "/Item/Add",
data: table.$('input, select').serialize(),
type: "POST",
dataType: "json",
success: function (result) {
alert("success: " + result);
},
error: function (errormessage) {
alert("error: " + errormessage);
}
});
}
} );
});
不能在javascript对象中使用combine .serialize()
,使用.serialize()
时需要使用默认的contentType
('application/x-www-form-urlencoded; charset=UTF-8'
)无论如何。
一个选项是在名称属性中包含集合索引器,这样表单控件的 name
属性是 name="[#].ItemType"
,其中 #
是从零开始的连续的索引器,在这种情况下 ajax 调用可以是
$.ajax({
url: "/Item/Add",
data: table.$('input, select').serialize(),
type: "POST",
....
然而,由于您似乎也想删除项目,这也意味着您需要在每一行中为集合索引器(例如 <input name="Index" value="#">
)添加一个输入。
或者,您需要根据每个 <tr>
中每个表单控件的值生成对象数组,将其字符串化,然后使用 contentType: 'application/json'
发送
构建数组
var arr = [];
// adjust following to exclude any tr elements in a thead or tfoot if applicable
var rows = $('#ItemTable').find('tr');
$.each(rows, function(index, item) {
var controls = $(this).find('input, select');
var item = {
ItemType: controls.eq(0).val(),
Unit: controls.eq(1).val(),
Quantity: controls.eq(2).val(),
Price controls.eq(3).val(),
}
arr.push(item);
});
然后去post吧
$.ajax({
url: '@Url.Action("Add", "Item")', // don't hard code your urls
data: JSON.stringify(arr),
contentType: 'application/json',
type: "POST",
dataType: "json",
success: function (result) {
....
附带说明一下,您正在使用 name="Unit"
创建 <select>
,但您的模型中似乎没有具有该名称的 属性。此外,你给每个 <option>
相同的 value="select"
这是我的 ajax 电话:
$('#SaveItemButton').click(function () {
var tableData = { 'ItemViewModel': table.$('input, select').serialize() }; // here the data gets returned
//Add Data Function
function Add() {
$.ajax({
url: "/Item/Add",
data: tableData,
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (result) {
alert("success: " + result);
},
error: function (errormessage) {
alert("error: " + errormessage);
}
});
}
} );
这是我的控制器操作:
public JsonResult Add(List<ItemViewModel> ItemViewModel)
{
var x = ItemViewModel;
return Json(1, JsonRequestBehavior.AllowGet);
}
tableData返回的实际数据:
“ItemType=Type1&Unit=select&Quantity=12&Price=1000&Total=&ItemType=Type2&Unit=//select&Quantity=11&Price=2000&Total="
我的控制器操作正在接收 ItemViewModel = null。谁能告诉我我需要如何处理收到的数据,以便我可以成功回发到服务器并绑定到模型:
public class ItemViewModel
{
public int Id { get; set; }
public string ItemType { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public ICollection<ProductViewModel> Products { get; set; }
public ICollection<ServiceViewModel> Services { get; set; }
public ICollection<CustomerViewModel> Customers { get; set; }
public InvoiceViewModel Invoice { get; set; }
public string ApplicationUserID { get; set; }
public int ProductId { get; set; }
public int ServiceId { get; set; }
public int InvoiceId { get; set; }
public int CustomerId { get; set; }
public string InvoiceDate { get; set; }
public string TransferDate { get; set; }
public string TransferPlace { get; set; }
public string InvoiceDescription { get; set; }
}
这是我的观点:
@using (Html.BeginForm("Add", "Item", FormMethod.Post, new { @class = "form-horizontal", id = "ItemForm", role = "form" }))
{
<body>
<h2>Invoice</h2>
<table id="ItemTable" class="table table-hover table-secondary" style="width:100%">
<thead>
<tr>
<th></th>
<th>ItemType</th>
<th>Unit</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
<th></th>
</tr>
</thead>
</table>
</body>
}
这是 jquery 数据表,javascript:
$(document).ready(function () {
var table = $('#ItemTable').DataTable({
"dom": '<"toolbar">frtip',
"paging": true,
"pagingType": "full_numbers",
"searching": false,
responsive: {
details: {
type: 'column'
}
},
columnDefs: [{
className: 'control',
orderable: false,
targets: 0
}],
order: [1, 'asc']
});
$("div.toolbar").html(
'<button id="addRow" type="button" class="btn btn-outline-info fa fa-plus"> Add</button> <div class="divider"/>' +
'<button id="SaveItemButton" type="submit" class="btn btn-outline-secondary fa fa-save"> Save</button> <div class="divider"/>' +
'<button id="PreviewButton" type="button" class="btn btn-outline-info fa fa-eye"> Preview</button> <div class="divider"/>' +
'<button id="PrintButton" type="button" class="btn btn-info fa fa-print"> Print</button> <div class="divider"/>' +
'<button id="SendButton" type="button" class="btn btn-lump-sum fa fa-envelope"> Send</button> <div class="divider"/>' +
'<button id="DeleteButton" type="button" class="btn btn-secondary fa fa-trash"> Delete </button> <div class="divider"/>'
);
var counter = 1;
$('#addRow').on('click', function () {
table.row.add([
'',
'<input name="ItemType" class="form-control" type="text">',
'<select name="Unit" class="form-control defaultpicker">' +
'<option value="select">dan</option>' +
'<option value="select">Komad</option>' +
'<option value="select">Sat</option>' +
'<option value="select">m</option>' +
'<option value="select">m2</option>' +
'<option value="select">m3</option>' +
'<option value="select">kg</option>' +
'<option value="select">lit</option>' +
'<option value="select">pak</option>' +
'<option value="select">reč</option>' +
'</select > ',
'<input name="Quantity" class="form-control" type="number">',
'<input name="Price" class="form-control" type="text">',
'<input name="Total" class="form-control" type="text" readonly>',
'<button type="button" Id="DeleteButton" class="fa fa-times select-row btn btn-secondary btn-sm" data-id=""></button>',
]).draw(false);
counter++;
$('#ItemTable').dataTable().fnPageChange('last');
});
$('#ItemTable').on("click", "#DeleteButton", function () {
var table = $('#ItemTable').DataTable();
var row;
console.log($(this).closest('table'));
if ($(this).closest('table').hasClass("collapsed")) {
var child = $(this).parents("tr.child");
row = $(child).prevAll(".parent");
} else {
row = $(this).parents('tr');
}
table.row(row).remove().draw();
});
// Automatically add a first row of data
$('#addRow').click();
$('#SaveItemButton').click(function () {
debugger;
//Add Data Function
function Add() {
$.ajax({
url: "/Item/Add",
data: table.$('input, select').serialize(),
type: "POST",
dataType: "json",
success: function (result) {
alert("success: " + result);
},
error: function (errormessage) {
alert("error: " + errormessage);
}
});
}
} );
});
不能在javascript对象中使用combine .serialize()
,使用.serialize()
时需要使用默认的contentType
('application/x-www-form-urlencoded; charset=UTF-8'
)无论如何。
一个选项是在名称属性中包含集合索引器,这样表单控件的 name
属性是 name="[#].ItemType"
,其中 #
是从零开始的连续的索引器,在这种情况下 ajax 调用可以是
$.ajax({
url: "/Item/Add",
data: table.$('input, select').serialize(),
type: "POST",
....
然而,由于您似乎也想删除项目,这也意味着您需要在每一行中为集合索引器(例如 <input name="Index" value="#">
)添加一个输入。
或者,您需要根据每个 <tr>
中每个表单控件的值生成对象数组,将其字符串化,然后使用 contentType: 'application/json'
构建数组
var arr = [];
// adjust following to exclude any tr elements in a thead or tfoot if applicable
var rows = $('#ItemTable').find('tr');
$.each(rows, function(index, item) {
var controls = $(this).find('input, select');
var item = {
ItemType: controls.eq(0).val(),
Unit: controls.eq(1).val(),
Quantity: controls.eq(2).val(),
Price controls.eq(3).val(),
}
arr.push(item);
});
然后去post吧
$.ajax({
url: '@Url.Action("Add", "Item")', // don't hard code your urls
data: JSON.stringify(arr),
contentType: 'application/json',
type: "POST",
dataType: "json",
success: function (result) {
....
附带说明一下,您正在使用 name="Unit"
创建 <select>
,但您的模型中似乎没有具有该名称的 属性。此外,你给每个 <option>
相同的 value="select"