我正在创建一个页面,用户可以在其中输入与客户相关的详细信息(例如姓名,参考编号,日期),并在该页面下方填写表格(行数是动态的,不确定用户将拥有多少行)从客户收到。每个表行都有与项目相关的信息,例如部件名称,部件号,数量等。除了这些信息,我们还需要上载接收到的纸张物理副本的图像(单个图像)。我们必须将所有这些数据发送到控制器。尝试在JavaScript和Ajax中使用FormData,如下所示:
function Submitbtn() {
var shownVal = document.getElementById("CustomerId").value;
var CustomerId = document.querySelector("#CNList option[value='" + shownVal + "']").dataset.value;
var formData = new FormData();
var totalFiles = document.getElementById("imageUploadForm").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("imageUploadForm").files[i];
formData.append("imageUploadForm", file);
}
formData.append("CustomerRef", document.getElementById("CustomerRef").value);
formData.append("DateCreated",$("#DateCreated").val());
formData.append("ChallanDate", $("#ChallanDate").val());
$('.signal').show()
$.ajax({
url: '@Url.Action("SubmitData", "Material")',
type: "POST",
processData: false,
contentType: false,
data: formData,
success: function (response) {
$('.signal').hide();
if (data.result == false) {
alert(data.msg);
}
else {
alert("Saved succesfully");
$('#updateData').html(data);
}
},
error: function (er) {
alert(er);
}
});
}
ControllerCode:
public ActionResult SubmitData()
{
var pic = System.Web.HttpContext.Current.Request.Files["imageUploadForm"];
var id = System.Web.HttpContext.Current.Request.Params["InvoiceViewModel"];
Code processing
InvoiceViewModel vm = new InvoiceViewModel();
return PartialView("_AddNewTable", vm);
}
以上方法工作正常,但我无法发送相关的表格数据。我可以为CustomerRef,ChallanDate等发送值。但是无法在其中附加arraylist。 在我看来,如果我在formData中追加一个数组列表,则无法在控制器中检索到它,因为它仅期望字符串值。
如果我们不发送图像,则所有数据将通过ajax成功发送到控制器,如下所示:
var shownVal = document.getElementById("CustomerId").value;
var CustomerId = document.querySelector("#CNList option[value='" + shownVal + "']").dataset.value;
var CustomerRef = document.getElementById("CustomerRef").value;
var DateCreated = $("#DateCreated").val();
var ChallanDate = $("#ChallanDate").val();
var InwardMaterialViewModel = {
DateCreated: DateCreated,
ChallanDate: ChallanDate,
CustomerId: CustomerId,
CustomerRef: CustomerRef,
Orders: InwardMaterialArray,
};
$.ajax({
beforeSend: function () {
$('.signal').show()
},
type: 'POST',
url: '@Url.Action("SubmitData", "Material")',
datatype: "json",
contentType: false,
processData: false,
data: InwardMaterialViewModel,
success: function (data) {
$('.signal').hide();
if (data.result == false) {
alert(data.msg);
}
else {
alert("Saved succesfully");
$('#updateData').html(data);
}
},
error: function (response) {
}
});
试图将图像文件放置在InwardMaterialViewModel
中,但这没有用。
研究发现,我们可以使用<form action="" method="post" enctype="multipart/form-data">
方法发送数据和图像,如以下链接中所述:https://cpratt.co/file-uploads-in-asp-net-mvc-with-view-models/
但是接下来的问题是,由于我们不知道用户将输入多少行,因此表数据未按模型发送。请告知。
根据要求提供更多信息:
主视图:
@model xxxx.ViewModels.InwardMaterialViewModel
@{
ViewBag.Title = "AddNew";
}
<h2>AddNew</h2>
<link href="~/Content/Loader.css" rel="stylesheet" type="text/css" />
<div class="container margin-top-lg">
<div class="row">
<div class="col-lg-12">
<div class="col-sm-6">
<div class="form-group">
<label for="DateCreated">Date :</label>
@Html.TextBoxFor(d => d.DateCreated, "{0:dd/MM/yyyy}", new { id = "DateCreated", @class = "form-control", maxlength = "500" })
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="CustomerName">Customer Name :</label>
@*@Html.EditorFor(model => model.CustomerRef, new { id = "CustomerName", htmlAttributes = new { @class = "form-control" } })*@
@*@Html.DropDownListFor(p => p.Customers, new SelectList(Model.Customers, "CustomerId", "CustomerName"), "Select Name", new { id = "CustomerId", @class = "form-control" })*@
<input name="id" class="form-control" type="search" list="CNList" autocomplete="on" id="CustomerId" />
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="CustomerRef">Customer Ref. :</label>
@Html.TextBoxFor(d => d.CustomerRef, new { id = "CustomerRef", @class = "form-control", maxlength = "2000" })
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="CustomerRef">Challan Date :</label>
@Html.TextBoxFor(d => d.ChallanDate, "{0:dd/MM/yyyy}", new { id = "ChallanDate", @class = "form-control", maxlength = "500" })
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<div class="field" align="left">
<label for="ChallanImage">Challan Image :</label>
<input type="file" id="imageUploadForm" name="images" multiple="multiple" />
</div>
</div>
</div>
<br />
<div class="col-md-12">
<div id="updateData" class="table-responsive">
@Html.Partial("_AddNewTable")
</div>
</div>
<br>
</div>
<br />
<a href="@Url.Action("Index", "Home")" class="btn btn-primary btn-large pull-left"> Back</a>
<button type="submit" id="id" onclick="Submitbtn()" class="btn btn-success pull-right"> Submit </button>
部分视图:带有表数据
@model xxxx.ViewModels.InwardMaterialViewModel
<table id="data_table">
<tr>
<th>Part Name</th>
<th>Part No</th>
<th>Serial No</th>
<th>Quantity</th>
<th>Repair Type</th>
<th>User</th>
<th>Remarks</th>
<th>Add/Delete</th>
</tr>
@foreach (var item in Model.Orders)
{
<tr>
<td>@item.PartName</td>
<td>@item.PartNo</td>
<td>@item.SerialNo</td>
<td>1</td>
<td>@item.RepairType</td>
<td>@item.UserName</td>
<td>@item.Remarks</td>
<td>
<input type='button' value='Delete' class='delete' onclick='Delete(@item.OrderGUID)' />
</td>
</tr>
}
<tfoot>
<tr>
<td><input name="id" class="form-control" type="search" list="lan" autocomplete="on" id="Part_Name" onchange = "getPartNumber()" /></td>
@*<td>@Html.DropDownListFor(p => p.Parts, new SelectList(Model.Parts, "PartName", "PartName"), "Select Name", new { id = "Part_Name", @class = "form-control", @onchange = "getPartNumber()" })</td>*@
<td><input type="text" class="form-control" id="Part_No" readonly/></td>
<td><input type="text" class="form-control" id="Serial_No" /></td>
<td><input type="text" class="form-control" id="Quantity" value="1" readonly/></td>
<td>
@Html.DropDownListFor(p => p.RepairType, new SelectList(Model.RepairTypeList, "Text", "Value"), "Select Type", new { id = "Repair_Type", @class = "form-control" })
</td>
<td>
@Html.DropDownListFor(p => p.Users, new SelectList(Model.Users, "UserId", "UserName"), "Select Name", new { id = "User", @class = "form-control" })
</td>
<td><input type="text" class="form-control" id="Remarks" /></td>
<td>
<input type="button" class="add" onclick="add_row();" value="Add Row">
</td>
</tr>
</tfoot>
</table>
<datalist id="lan">
@foreach (var item in Model.Parts)
{
<option id="@item.PartId" data-value="@item.PartId" value="@item.PartName"></option>
}
</datalist>
在add_row上:将行数据输入到数组中
var InwardMaterialArray = [];
function add_row() {
var Part_Name = document.getElementById("Part_Name").value;
var Part_No = document.getElementById("Part_No").value;
var Serial_No = document.getElementById("Serial_No").value;
if (Serial_No == "") {
alert("Serial No. must be filled out");
return false;
}
var Quantity = document.getElementById("Quantity").value;
var Repair_Type = document.getElementById("Repair_Type").value;
var User = document.getElementById("User").value;
var Remarks = document.getElementById("Remarks").value;
var OrderDto = {
PartName: Part_Name,
PartNo: Part_No,
SerialNo: Serial_No,
Qty: Quantity,
RepairType: Repair_Type,
AssignedUserId: User,
Remarks: Remarks,
};
InwardMaterialArray.push(OrderDto);
var InwardMaterialViewModel = {
Orders : InwardMaterialArray
};
$.ajax({
beforeSend: function () {
$('.signal').show()
},
type: 'POST',
url: '@Url.Action("AddRow", "Material")',
data: InwardMaterialViewModel,
success: function (data) {
$('.signal').hide();
if (data.result == false) {
alert(data.msg);
}
else {
$('#updateData').html(data);
}
},
error: function (response) {
}
});
}
所有在行中输入的数据都位于上述InwardMaterialArray
方法中通过InwardMaterialArray.push(OrderDto);
填充的数组列表add_row
中。
因此,我需要一次将此数组InwardMaterialArray
以及上面为客户和图像填充的数据发送到控制器。