I am trying to post multiple arrays to my controller using Ajax post. First I have a model like this:
public class EnrollmentOptionsVM
{
public virtual string OptionID{ set;get;}
public virtual string UserChoice { set;get;}
public virtual string TchOptionID { set; get; }
public virtual string TeacherChoice { set; get; }
}
Then my script:
<script type="text/javascript">
var $checkboxes = $('input[type="checkbox"]');
var $strInstructors = $('input[name="instructorString"]');
$(document).ready(function () {
$('#saveBtn').click(function () {
var teacherOptions = [];
var options = [];
$.each($checkboxes, function () {
if ($(this).is(':checked')) {
var item = { "UserChoice": "checked", "OptionID": "YouCanSetIDHere" };
}
else {
var item = { "UserChoice": "unchecked", "OptionID": "YouCanSetIDHere" };
}
options.push(item);
})
$.each($strInstructors, function () {
if ($(this).is(':selected')) {
var tchItem = { "TeacherChoice": "checked", "TchOptionID": "SetTchIDHere" };
}
else {
var tchItem = { "TeacherChoice": "unchecked", "TchOptionID": "SetTchIDHere" };
}
options.push(tchItem);
})
$.ajax({ type:
'POST', url: '#Url.Action("EnrollmentRefresh", "Student")',
contentType: 'application/json',
data: JSON.stringify({firstArray:options, secondArray:teacherOptions})
}).done(function (html) {
});
});
});
</script>
And in my controller here’s the action signature:
[HttpPost]
public ActionResult EnrollmentRefresh(List<EnrollmentOptionsVM> checkedOptions)
{}
When I send only options like this: data: JSON.stringify(options)… it works but when I try to send multiple arrays like the code above it returns null in the controller. How can post multiple arrays using JSON.stringify()?
UPDATE 1
<script type="text/javascript">
var $checkboxes = $('input[type="checkbox"]');
var $strInstructors = $('input[name="instructorString"]');
$(document).ready(function () {
$('#saveBtn').click(function () {
var teacherOptions = [];
var options = [];
$.each($checkboxes, function () {
if ($(this).is(':checked')) {
var item = { "UserChoice": "checked", "OptionID": "YouCanSetIDHere" };
}
else {
var item = { "UserChoice": "unchecked", "OptionID": "YouCanSetIDHere" };
}
options.push(item);
})
$.each($strInstructors, function () {
if ($(this).is(':selected')) {
var tchItem = { "TeacherChoice": "checked", "TchOptionID": "SetTchIDHere" };
}
else {
var tchItem = { "TeacherChoice": "unchecked", "TchOptionID": "SetTchIDHere" };
}
teacherOptions.push(tchItem);
})
$.ajax({ type:
'POST', url: '#Url.Action("EnrollmentRefresh", "Student")',
contentType: 'application/json',
data: JSON.stringify({checkedOptions:options,selectedTeacher:teacherOptions})
}).done(function (html) {
});
});
});
</script>
And in the controller:
[HttpPost]
public ActionResult EnrollmentRefresh( List<EnrollmentOptionsVM> checkedOptions, List<TeacherOptionMV> selectedTeachers)
{}
Two ViewModels
public class TeacherOptionMV
{
public virtual string TchOptionID { set; get; }
public virtual string TeacherChoice { set; get; }
}
And
public class EnrollmentOptionsVM
{
public virtual string OptionID{ set;get;}
public virtual string UserChoice { set;get;}
}
You are not posting multiple arrays with {firstArray:options, secondArray:teacherOptions}. You are posting a single object with two properties: firstArray and secondArray. Your controller is designed to get only one array of EnrollmentOptionsVM. The best thing to do, I guess, is to change EnrollmentRefresh method to take some object with fields firstArray and secondArray (or something like that) as an argument.
Related
When I set a breakpoint on LoadReport, every parameter is null. For some reason the values are not binding to the parameters with the same name.
Javascript/AJAX
$('#savedCriteria').on('change', function () {
var criteriaSelected = $('#savedCriteria option:selected').text();
var data = { actionName: "Daily", reportInput: "ReportDaily", reportCriteria: criteriaSelected };
//Ajax form post
$.ajax({
type: 'POST',
data: data,
contentType: "application/json; charset=utf-8",
url: '#Url.Action("LoadReport", ViewContext.RouteData.Values["Controller"].ToString())',
success: function (data) {
if (data.success) {
alert("Test");
} else {
alert("Test Not Successful");
}
}
});
});
Controller
public void LoadReport(string actionName, string reportInput, string reportCriteria)
{
var reportObject = Activator.CreateInstance(Type.GetType(reportInput));
IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(reportInput);
RedirectToAction(actionName, "Reports", reportList.Where(x => x.CriteriaName == reportCriteria));
}
Default method type is HttpGet, you need to set it to HttpPost.
[HttpPost]
public void LoadReport(string actionName, string reportInput, string reportCriteria)
{
var reportObject = Activator.CreateInstance(Type.GetType(reportInput));
IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(reportInput);
RedirectToAction(actionName, "Reports", reportList.Where(x => x.CriteriaName == reportCriteria));
}
Also keep in mind that with your ajax call you can not use RedirectToAction. You need something like this:
[HttpPost]
public ActionResult LoadReport(string actionName, string reportInput, string reportCriteria)
{
var reportObject = Activator.CreateInstance(Type.GetType(reportInput));
IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(reportInput);
Return Json(Url.Action(actionName, "Reports", reportList.Where(x => x.CriteriaName == reportCriteria));
}
And in your ajax call:
success: function (data) {
window.location.href = data;
}
UPDATE: you also need to create a POCO object and add that to the HttpPost method as parameter instead of separate parameters. Also [FromBody] attribute is needed.
POCO:
public class Data
{
public string actionName { get; set; }
public string reportInput { get; set; }
public string reportCriteria { get; set; }
}
Controller:
[HttpPost]
public JsonResult LoadReport([FromBody]Data data)
{
var reportObject = Activator.CreateInstance(Type.GetType(data.reportInput));
IEnumerable<Test.Reports.Utilities.ReportCriteria> reportList = getReportCriteria(data.reportInput);
return Json(Url.Action(data.actionName, "Reports"));
}
I have these ViewModels:
public class UserAddRoleListViewModel
{
public String Id { get; set; }
public String Name { get; set; }
}
public class SaveUserNewRoleViewModel
{
[Required]
public String RoleId { get; set; }
public String RoleName { get; set; }
public List<UserAddRoleListViewModel> RoleList { get; set; }
}
How can I pass an array of objects that have a format like this:
var object = {
Id: rowIdItem,
Name: rowItem
};
dataSet.push(object);
to my MVC Controller here:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult VerifyRole(SaveUserNewRoleViewModel Input)
{
IEnumerable<object> errors = null;
if (ModelState.IsValid)
{
if(Input.RoleList[0] != null)
{
foreach (var item in Input.RoleList)
{
if (Input.RoleId == item.Id)
{
ModelState.AddModelError("RoleId", "Role already exists");
errors = AjaxError.Render(this);
return Json(new { success = false, errors });
}
}
return Json(new { success = true });
}
return Json(new { success = true });
}
else
{
errors = AjaxError.Render(this);
return Json(new { success = false, errors });
}
}
So far it seems like its always passing an nothing when I debug it
EDIT:
Just to clarify. I can already pass the item via ajax. It's just that when I debug, RoleList is empty.
This is my ajax function:
$(document).on("submit", "#modal", function (e) {
e.preventDefault();
var selectedText = $("##Html.IdFor(m=>m.RoleId) :selected").text();
var selectedId = $("##Html.IdFor(m=>m.RoleId)").val();
var form_data = $(this).serializeArray();
form_data.push({ name: "RoleList", value: dataSet });
console.log(form_data);
rowIdItem = selectedId;
rowItem = selectedText;
$("#close").trigger("click");
$.ajax({
url: "#Url.Action("VerifyRole", #ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
data: form_data,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (result) {
if (result.success) {
rowIdItem = selectedId;
rowItem = selectedText;
$("#close").trigger("click");
return;
}
$.each(result.errors, function (index, item) {
// Get message placeholder
var element = $('[data-valmsg-for="' + item.propertyName + '"]');
element.empty();
// Update message
element.append($('<span></span>').text(item.errorMessage));
// Update class names
element.removeClass('field-validation-valid').addClass('field-validation-error');
$('#' + item.propertyName).removeClass('valid').addClass('input-validation-error');
});
}
});
return false;
});
EDIT 2:
Added code that fills dataSet:
$(document).on($.modal.AFTER_CLOSE, function (event, modal) {
dataSet.push(object);
table.row.add(object).draw();
$("#modal").empty();
});
Javascript
$("#myBtn").click(function () {
var dataSet= [];
var obj = {
Id: rowIdItem,
Name: rowItem
};
dataSet.push(obj);
var data = {
"RoleId": '1',
"RoleName ": 'roleName',
"RoleList": dataSet
};
$.ajax({
type: "POST",
traditional:true,
url: "controller/VerifyRole",
content: "application/json;",
dataType: "json",
data: data ,
success: function () {
}
});
});
Controller/Action
[HttpPost]
public ActionResult VerifyRole(SaveUserNewRoleViewModel input)
{
...
}
Try this:)
$(document).on("submit", "#modal", function (e) {
e.preventDefault();
var selectedText = $("##Html.IdFor(m=>m.RoleId) :selected").text();
var selectedId = $("##Html.IdFor(m=>m.RoleId)").val();
var form_data = {};
form_data.RoleId = selectedId;
form_data.RoleName =selectedText;
console.log(form_data);
rowIdItem = selectedId;
rowItem = selectedText;
$("#close").trigger("click");
$.ajax({
url: "#Url.Action("VerifyRole", #ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
data: JSON.stringify(form_data),
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (result) {
if (result.success) {
rowIdItem = selectedId;
rowItem = selectedText;
$("#close").trigger("click");
return;
}
$.each(result.errors, function (index, item) {
// Get message placeholder
var element = $('[data-valmsg-for="' + item.propertyName + '"]');
element.empty();
// Update message
element.append($('<span></span>').text(item.errorMessage));
// Update class names
element.removeClass('field-validation-valid').addClass('field-validation-error');
$('#' + item.propertyName).removeClass('valid').addClass('input-validation-error');
});
}
});
return false;
});
my example with datasets:
$("body").on("click", "#btnSave", function () {
var ops = new Array();
$("#table TBODY TR").each(function () {
var row = $(this);
var ps = {};
ps.colname1 = row.find("TD").eq(0).html();
ps.colname2 = row.find("TD").eq(1).html();
ps.colname3= row.find("TD").eq(2).html();
ops.push(ps);
});
var item = {};
item.nam1 = "test";
item.List = ops;
$.ajax({
type: "POST",
url: " ...",
data: JSON.stringify(item),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
}
});
});
I have a class with an array property in MVC
public class MyClass
{
public int Contrato_Id { get; set; }
public string Contrato { get; set; }
public int Torre_Id { get; set; }
public string Torre { get; set; }
public SkillsATB[] Skills { get; set; }
}
When I do the POST via jquery ajax my ModelState validation is always false
if (ModelState.IsValid)
{
var _current = _Service.Insert(current);
return Json(new { result = "success", resultValue = "" });
}
debuggin image here here
The property SkillsATB is ok, it has elements, but I think I am missing something for that array.
function ConvertToSkillsObject(id, name) {
var skill = {
Id: Math.round(id),
Nombre: name,
Descripcion: "",
Activo: "1",
Asignada: 1
}
return skill;
}
function GetSkillsAsignados() {
var asignados = [];
$("#sortable2").children().each(function () {
var item = ConvertToSkillsObject($(this).attr("data-id"), $(this).html())
asignados.push(item);
});
return asignados;
}
var MyClass= {
Correo: $('#correo').val(),
CorreoLider: $('#correoLider').val(),
CorreoLiderBSD: $('#correoLiderBSD').val(),
FechaNacio: $('#fechaNacio').val(),
Contrato_Id: $('#contrato_Id').val(),
Torre_Id: $('#torre_Id').val(),
Skills: GetSkillsAsignados()
};
$.ajax({
url: "../../MyController/Save",
type: "POST",
data: JSON.stringify(MyClass),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (e) {
... //more javascript
Remove the property from the model before validating: ModelState.Remove("Skills");
SOLVED
The problem was in a datepicker CSS, something was wrong in the format date. Nothing to do with the prior before
I was trying several ways to pass the list of objects to the controller but
the controller always receives null
Here is my code:
View:
$('#btnSave').click(function () {
var arrPropIdPos = new Array();
$('.property').each(function () {
var obj = {
PropertyId : $(this).attr('PropertyId'),
Xposition : $(this).attr('xPos'),
Yposition : $(this).attr('yPos')
};
arrPropIdPos.push(obj);
});
var jsonData = JSON.stringify(arrPropIdPos);
$.ajax({
url: "/PropertyPosition/Insert/",
type: 'POST',
data: jsonData,
dataType: 'json',
//...
},
console.log(arrPropIdPos);
0: Object
PropertyId: "1"
Xposition: "11"
Yposition: "55"
__proto__: Object
1: Object
PropertyId: "2"
Xposition: "651"
Yposition: "48"
__proto__: Object
console.log(jsonData);
[{"PropertyId":"1","Xposition":"11","Yposition":"55"},
{"PropertyId":"2","Xposition":"651","Yposition":"48"}]
Controller (option 1):
[HttpPost]
public JsonResult Insert(string jsonData)
{
// jsonData is null
}
Controller (option 2):
public class PropertyPositionInsert
{
public string PropertyId { get; set; }
public string Xposition { get; set; }
public string Yposition { get; set; }
}
public JsonResult Insert(List<PropertyPositionInsert> model)
{
// model is null
}
Try to wrap your array into an object with a property model:
var jsonData = JSON.stringify({model: arrPropIdPos});
Also try to set dataType option to 'application/json'.
$('#btnSave').click(function () {
var arrPropIdPos = new Array();
$('.property').each(function () {
var obj = {
'PropertyId' : $(this).attr('PropertyId')
,'Xposition' : $(this).attr('xPos')
,'Yposition' : $(this).attr('yPos')
};
arrPropIdPos.push(obj);
});
$.ajax({
type: 'POST',
contentType: "application/json",
data: JSON.stringify(arrPropIdPos),
url: "/PropertyPosition/Insert/"
});
Class:
public class PropertyPositionInsert
{
public string PropertyId { get; set; }
public string Xposition { get; set; }
public string Yposition { get; set; }
}
Controller:
public JsonResult Insert(PropertyPositionInsert[] model)
{
}
I have run into this in the past and have found that if you set
traditional: true
in your jQuery ajax call, it shjould fix the issue.
$('#btnSave').click(function () {
var arrPropIdPos = new Array();
$('.property').each(function () {
var obj = {
PropertyId : $(this).attr('PropertyId'),
Xposition : $(this).attr('xPos'),
Yposition : $(this).attr('yPos')
};
arrPropIdPos.push(obj);
});
var jsonData = JSON.stringify(arrPropIdPos);
$.ajax({
beforeSend: function () {
},
type: "POST",
"async": true,
url: "/PropertyPosition/Insert/",
data: JSON.stringify(obj),
dataType: "json",
contentType: "application/json",
success: function (data) {
},
error: function (xhr, textStatus, error) {
},
complete: function () {
},
})
Controller:
Create a class or model
public class PropertyPositionInsert
{
public string PropertyId { get; set; }
public string Xposition { get; set; }
public string Yposition { get; set; }
}
public IHttpActionResult JsonResult (PropertyPositionInsert obj)
{
obj.PropertyId;
obj.Xposition ;
obj.Yposition;
}
you can check the values in above obj
I need some help. I write little app using ASP.NET MVC5 with JavaScript, jQuery, Ajax... and I can't send data from javascript to MVC Controller and change the model.
ViewModel
public class MyViewModel
{
//...
public string SearchString { get; set; }
public int? FirstInt { get; set; }
public int? SecondInt { get; set; }
}
Javascript
function keystroke() {
var a = 0, b = 0;
$('#search').keyup(function (event) { a = 1; });
$('#search').keydown(function (event) { b = 1; });
$("#search").keypress(function (event) {
if (e.which === 13) {
e.preventDefault();
$('form').click(function () {
sendForm(a, b);
});
}
});
};
function sendForm(a, b) {
$.ajax({
url: #Url.Action("Index", "Home"),
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
FirstInt: a,
SecondInt: b
}),
success: function () {
alert('success');
}
});
};
View
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { #class = "form-inline", role = "form" }))
{
<div class="form-group has-feedback">
#Html.TextBox("SearchString", ViewBag.SearchFilter as string, new
{
#class = "form-control",
onclick="keystroke()",
id = "search"
})
</div>
}
Controller
public async Task<ActionResult> Index(MyViewModel model)
{
//...
if (model.SearchString != null)
{
//...
var a = model.FirstInt;
var b = model.SecondInt;
}
//...
return View(model);
}
Help me, please, to send all the values to controller. Those that changed in JavaScript and what I enter in the textbox. Thanks.
Javascript Code:
function keystroke() {
var a = 0, b = 0;
$('#search').keyup(function (event) { a = 1; });
$('#search').keydown(function (event) { b = 1; });
$("#search").keypress(function (event) {
if (e.which === 13) {
e.preventDefault();
$('form').click(function () {
var text = $("#search").val()
sendForm(a, b, text);
return false;
});
}
});
};
function sendForm(a, b, text) {
var data = {FirstInt: a,SecondInt: b,SearchString: text}
$.ajax({
url: 'Home/Index',
type: 'POST',
contentType: 'application/json',
data: data,
success: function () {
alert('success');
}
});
};
Controller Code
[HttpPost]
public async Task<ActionResult> Index(MyViewModel model)
{
//...
if (model.SearchString != null)
{
//...
var a = model.FirstInt;
var b = model.SecondInt;
}
//...
return View(model);
}