问题
I have a long strongly-typed form which its inputs are bound with viewmodel as html helpers, while i have a table that's not strongly-typed, it's generated when user clicks Add button, and i collect its data as json. how to map json data to viewmodel and send as one unit to post action in controller in ajax call?
view
@model SIServices.ViewModels.SODViewModel
@using (Html.BeginForm("Initiate", "SOD", FormMethod.Post, new { id =
"initiateSOD" })) // enctype = "multipart/form-data"
{
@Html.AntiForgeryToken()
...
@* form inputs as html helpers *@
@* html table data is collected as json *@
javasctipt
var cols = [];
cols.push("DIGITAL_FILE_TYPE_ID");
cols.push("DOCUMENT_LAPI_ID");
var DigitalMaps = [];
$("table#digital-map-table tbody tr").each(function () {
data = {};
var selectedDigitalMapVal = $(this).data("selectedDigitalMapVal");
data[cols[0]] = selectedDigitalMapVal;
var documentId = $(this).data("documentID");
data[cols[1]] = documentId.toString();
DigitalMaps.push(data);
data = {};
});
var headers = { __RequestVerificationToken:
$('input[name="__RequestVerificationToken"]').val() };
if (DigitalMaps != null) {
$.ajax({
headers: headers,
url: "@Url.Action("Initiate")",
type: "POST",
cache: false,
contentType: "application/json; charset=utf-8",
data: DigitalMaps,
dataType: "json",
success: function (succ) {
console.log(succ);
},
error: function (err) {
console.log(err.statusText);
}
});
}
viewmodel
namespace SIServices.ViewModels
{
public class SODViewModel
{
// a lot of properties - around 50
public int? DigitalMapId { get; set; }
public List<DIGITAL_MAPS> DigitalMaps { get; set; }
controller
[HttpPost]
[ValidateHeaderAntiForgeryToken]
public ActionResult Initiate(SODViewModel vm)
{
回答1:
You've got a form, backed by the view model, which you need to convert to a JavaScript Object so you can attach the DigitalMaps
array.
To tackle the first problem you can use one of the answers here Convert form data to JavaScript object with jQuery.
Below, I use the function from here https://stackoverflow.com/a/22420377/2030565. This worked on a simple form but I haven't tried to find edge cases.
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
So we can capture the form and convert it to a JavaScript object:
var model = $("form").serializeObject();
Now we can attach the property for the collection:
var digitalMapRows = [];
model.DigitalMaps = digitalMapRows;
Then post with ajax
$.ajax({
headers: headers,
url: "@Url.Action("Initiate")",
type: "POST",
cache: false,
contentType: "application/json; charset=utf-8",
data: JSON.stringify(model),
dataType: "json",
success: function (succ) {
console.log(succ);
}
});
来源:https://stackoverflow.com/questions/56194690/how-to-bind-json-data-to-existing-viewmodel-mvc5