I know this is some pretty old technology, but this issue with Datatables has been bothering me, and I haven't found a satisfactory answer on SO that deals with this specifically.
In my code, I have the following AJAX call. It serializes my form, posts the data to my .NET MVC controller, and no errors occur.
var url = "/Student/SectionSearch/";
var vm = $('#sectionSearchForm').serializeArray();
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: vm,
success: function (result) {
return false;
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to load sections. Please try again.');
}
});
Here is the heavily stripped-down form.
@model ViewModels.SectionSearchVM
@using (Html.BeginForm("SectionSearch", "Student", FormMethod.Post, new { @id = "sectionSearchForm" }))
{
<div>
<div>
@Html.LabelFor(model => model.CalendarId)
@Html.DropDownListFor(model => model.CalendarId, Model.Calendars, "")
</div>
<div>
@Html.LabelFor(model => model.StructureId)
@Html.DropDownListFor(model => model.StructureId, Model.Structures, "")
</div>
<div>
@Html.LabelFor(model => model.PeriodId)
@Html.DropDownListFor(model => model.PeriodId, Model.Periods, "")
</div>
<div>
@Html.LabelFor(model => model.TermId)
@Html.DropDownListFor(model => model.TermId, Model.Terms, "")
</div>
<div>
@Html.LabelFor(model => model.SectionId)
@Html.DropDownListFor(model => model.SectionId, Model.Sections, "")
</div>
</div>
<div>
<input id="submitSectionSearch" type="submit" value="Search">
</div>
}
In my MVC controller, I can see that the object was populated correctly, and a JSON-encoded list of my objects is returned without issues.
public JsonResult SectionSearch(SectionSearchVM vm)
{
StudentSearchResults results = _userService.GetStudentsBySectionId(vm.SectionId);
return Json(results, JsonRequestBehavior.AllowGet);
}
Now I'd like to run the exact same AJAX call, but from within the Datatables construct.
$('#resultsDataTable').DataTable({
info: false,
bFilter: false,
bLengthChange: false,
iDisplayLength: 10,
dom: 'rtp',
order: [[1, "asc"]],
language: {
emptyTable: "There are no students that meet your search criteria."
},
ajax: {
type: 'POST',
url: url,
dataType: 'json',
data: vm,
dataSrc: function (result) {
... data manipulation ...
return result.Results;
},
},
"autoWidth": false,
"columnDefs": [
{
"targets": 0,
"data": "StudentNumber",
},
{
"targets": 1,
"data": "FullName",
"width": "70%"
}
]
});
Inexplicably, this fails on the Controller side. The action is called correctly, but when debugging the code, I can see that my VM object is empty (all properties NULL).
I've tried doing some creative things to the datatables data object, including JSON.stringify(), serialize(), data: { "data": vm } but to no avail. I could change the endpoint to just accept a long query string of values, but to me, that defeats the purpose of serialization, and still doesn't explain why my AJAX call fails under slightly different circumstances.
Am I missing something fundamentally obvious here?
Update: It turns out there is a huge difference in the payloads that are passed between the standard AJAX call and the datatables version...
Standard:
CalendarId=6019&StructureId=10462&PeriodId=50141&TermId=21203&SectionId=3314793
Datatables:
0[name]=CalendarId&0[value]=6019&1[name]=StructureId&1[value]=10462&2[name]=PeriodId&2[value]=50141&3[name]=TermId&3[value]=21203&4[name]=SectionId&4[value]=3314793
Clearly that is part of my problem, but I still don't understand the hows or whys of it.
CodePudding user response:
I think the problem is in the form selector, where data is not serialize
as you using
var form = $('#sectionSearchForm');
var vm = $(form).serializeArray();
try these
var vm = $("form").serializeArray();
and
var vm = $("form").serialize();
CodePudding user response:
Unfortunately, I wasn't able to find a satisfactory reason for why this occurs with DataTables, so I'm back to using workarounds.
Here is the setup I went with, in the off-chance this might help someone else.
var vm = $('#sectionSearchForm').serializeArray();
var url = "/Student/SectionSearch/" "?" vm;
$('#resultsDataTable').DataTable({
dom: 'rtp',
order: [[1, "asc"]],
language: {
emptyTable: "There are no students that meet your search criteria."
},
ajax: {
type: 'POST',
url: url,
dataType: 'json',
data: null
},
"columnDefs": [
{
"targets": 0,
"data": "StudentNumber",
},
{
"targets": 1,
"data": "FullName",
"width": "70%"
}
]
});
Essentially, I nulled out the data parameter, and attached the serialized form as a huge query string on my URL. Not ideal, but it satisfied the DataTables construct.