Controller recieving empty data from Ajax - javascript

I'm trying to send a collection from a view to a controller, using ajax. First I complete the data in a javascript array, and then I try to pass it to the server:
var funciones = $("#funcionesUsuario").data("kendoGrid").dataSource.data();
var func = [];
for (var i = 0; i < funciones.length; i++) {
func.push({
"Estado": 1,
"FechaAlta": null,
"UsuarioAlta": null,
"FechaModificacion": null,
"UsuarioModificacion": null,
"BitConcilia": funciones[i].BitConcilia,
"BitLectura": funciones[i].BitLectura,
"BitSupervisa": funciones[i].BitSupervisa,
"ConciliacionId": funciones[i].ConciliacionId,
"UsuarioId": funciones[i].UsuarioId
})
}
$.post(url, { funcionesUsuario: func })
.done(function (data) {
alert("good job");
});
Then, since I'm sending data for 2 objects, my parameter is a IEnumerable of said object:
public void ActualizarFuncionesUsuario(IEnumerable<FuncionUsuario> funcionesUsuario)
{
//do something
}
My problem is that the controller receives 2 objects, as I can see in the funcionesUsuario.count, but they are both empty.
I tried sending int, bool and other types of variables with success, so I suspect I'm doing something wrong regarding data binding.
Below I attached pictures of what I'm sending and what I'm receiving in the other side.
This is the FuncionUsuario model: `
public class FuncionUsuario : AuditableEntity {
public int ConciliacionId { get; set; }
public int UsuarioId { get; set; }
public bool BitLectura { get; set; }
public bool BitConcilia { get; set; }
public bool BitSupervisa { get; set; }
public virtual Conciliacion Conciliacion { get; set; }
[Display(ResourceType = typeof(Global), Name = "Descripcion")]
[NotMapped]
public string Descripcion { get; set; }
}

first construct you array as java script objects
var funciones = $("#funcionesUsuario").data("kendoGrid").dataSource.data();
var func = [];
for (var i = 0; i < funciones.length; i++) {
func.push({
Estado: 1,
FechaAlta: null,
UsuarioAlta: null,
FechaModificacion: null,
UsuarioModificacion: null,
BitConcilia: funciones[i].BitConcilia,
BitLectura: funciones[i].BitLectura,
BitSupervisa: funciones[i].BitSupervisa,
ConciliacionId: funciones[i].ConciliacionId,
UsuarioId: funciones[i].UsuarioId
})
}
Next, properly stringify them
var payload = JSON.stringify(func);
Then post it as JSON
$.ajax({
url: url,
type: "POST",
contentType: "application/json",
dataType: 'json'
data: payload,
});

Try these:
Specify json as the dataType
$.post(url, { funcionesUsuario: func })
.done(function (data) {
alert("good job");
}, 'json');
Use $.ajax instead: docs
$.ajax({
url: url,
data: JSON.stringify(func),
contentType: "application/json",
type: "POST"
});

Related

.Net core - Ajax post does not pass variables to controller method

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"));
}

Posting JSON Array Collection to Asp.net Core Web API

Need your expertises
I am working with JS & Asp.net Core Web API.
I am trying to post a JSON Array to my API but i am failing to get data in web api post method it is NULL every time need help in understanding what is that I am missing..
Below is JS Code
function Trails(){
var A = [];
var B = [];
var MyData = [];
for(var i = 0;i <= 2;i++){
var _A = {
"ID" : i,
"_A" : "A"+i
};
A.push(_A);
}
for(var i = 0;i <= 2;i++){
var _B = {
"ID" : i,
"_B" : "B"+i
};
B.push(_B);
}
for(var i = 0;i <= 2;i++){
MyData.push({
"MyDataName" : "CJ"+i,
"A" : A,
"B" : B,
});
}
$.ajax({
crossDomain: true,
cache: false,
type: "POST",
url: "https://localhost:44359/api/values/",
contentType: "application/json",
data :JSON.stringify({MyData}),
dataType: "json",
success: function (data) {
alert(data);
}, //End of AJAX Success function
failure: function (data) {
alert(data.responseText);
console.log(data);
}, //End of AJAX failure function
error: function (data) {
alert(data.responseText);
console.log(data);
} //End of AJAX error function
});
}
C# Classes
public class A
{
public int ID { get; set; }
public string _A { get; set; }
}
public class B
{
public int ID { get; set; }
public string _B { get; set; }
}
public class MyData
{
public string MyDataName { get; set; }
public List<A> A { get; set; }
public List<B> B { get; set; }
}
Web API Post method
// POST api/values
[HttpPost]
public void Post([FromBody] List<MyData> MyData)
{
}
MyData is always null. please help
You are using: JSON.stringify({MyData}) instead of JSON.stringify(MyData). It goes to the server as a JSON containing field "MyData" with MyData, instead of just MyData array.

deserialize object when ajax call asmx web service

I have AJAX call where call web service. web service is should return value (token as a string). I tried my web service and try to invoke manually, it successfully retrieve the token as string. but, when I combine with AJAX call, it returns an object. How I can retrieve the value of the token?
here is my AJAX snippet
$.ajax({
url: "http://10.23.64.43:8035/iFrameIntegration.asmx/getToken",
data: JSON.stringify({ Token: { userName: 'crm' } }),
contentType: "application/json; charset=utf-8",
type: 'POST',
success: function (data) {
alert(data);
},
error: function (data) {
alert("Error");
}
});
and here is my web service (ASMX)
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string getToken()
{
var request = (HttpWebRequest)WebRequest.Create("http://10.23.64.37:8080/ACCMWS/member/SSOInit");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers["userId"] = "Svc_CRM";
request.Headers["loginType"] = "Internal";
request.Headers["token"] = "54a93982adf51adfb81885ddbbb1874e271605ce";
string result = string.Empty;
try
{
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = "{ \"userName\": \"crm\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
try
{
using (var response = request.GetResponse() as HttpWebResponse)
{
if (request.HaveResponse && response != null)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var resultTokenAwal = reader.ReadToEnd();
var resultToken = JsonConvert.DeserializeObject<RetrieveSSOTokenResult>(resultTokenAwal);
result = resultToken.data.ssotokenList[0].ssoToken;
}
}
}
}
catch (WebException e)
{
if (e.Response != null)
{
using (var errorResponse = (HttpWebResponse)e.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
result = error;
}
}
}
}
}
catch(Exception ex)
{
ex.Message.ToString();
}
return result;
}
and here is my class from my web service
public class RetrieveSSOTokenResult
{
public string status { get; set; }
public string message { get; set; }
public Data data { get; set; }
}
public class Data
{
public Ssotokenlist[] ssotokenList { get; set; }
}
public class Ssotokenlist
{
public string loginType { get; set; }
public string userName { get; set; }
public string userId { get; set; }
public string ssoToken { get; set; }
public long expiryTime { get; set; }
}
here is the result that I get when call from AJAX
{"d":"f0d7ef7e29b89d42e84d6590b8e7b52f899f3b7a"}
please advise, I only want to alert the value of the token, which is f0d7ef7e29b89d42e84d6590b8e7b52f899f3b7a.
in the asmx, when I try to invoke, I only got this information
var from resultTokenAwal is this
{"d":"status":"success","message":"","data":{"ssotokenList":[{"loginType":"Internal","userName":"CRM","userId":"E512E6D2-1584-4597-BBD6-01C724496107","ssoToken":"2f3b28def21bdace7bd7baacd0cd0bf72fbcb30b","expiryTime":1548047778532}]}}
but, in my asmx, the result of resultTokenAwal is this
{"status":"success","message":"","data":{"ssotokenList":[{"loginType":"Internal","userName":"CRM","userId":"E512E6D2-1584-4597-BBD6-01C724496107","ssoToken":"2f3b28def21bdace7bd7baacd0cd0bf72fbcb30b","expiryTime":1548047778532}]}}
UPDATE:
the data actually already parse in JSON in AJAX. so, just call the d. here is the update of AJAX.
$.ajax({
url: "http://10.23.64.43:8035/iFrameIntegration.asmx/getToken",
data: JSON.stringify({ Token: { userName: 'crm' } }),
contentType: "application/json; charset=utf-8",
type: 'POST',
success: function (data) {
alert(data.d);
},
error: function (data) {
alert("Error");
}
});

How can I validate my model when I have an array property?

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

Format JSon so that mvc4 controller method can parse it

My controller Action:
[HttpPost]
public ActionResult H80Count(IEnumerable<H80SearchCriteria> model)
{
do some stuff and return Json;
}
My model:
public class H80SearchCriteria
{
public int ID { get; set; }
public int Operator { get; set; }
public string FieldID { get; set; }
public string Kriterie { get; set; }
}
My Javascript:
var SearchCriteria = [];
var i = 0;
$('#tableSearchValues > tbody').find('tr').each(function () {
i += 1;
var row = {
ID : i,
Operator : $(this).data('operator'),
FieldID : $(this).data('fieldid'),
Kriterie: $(this).data('kriterie')
};
SearchCriteria.push(row);
});
var url = '/MyController/H80Count';
var data = JSON.stringify(SearchCriteria) ;
$.ajax({
type: 'POST',
url: url,
data: data,
etc...
The Json that is passed looks like this:
[{"ID":1,"Operator":1,"FieldID":1,"Kriterie":11211},{"ID":2,"Operator":1,"FieldID":1,"Kriterie":11211}]
I can't see why it is not parsed correctly. What am I missing?
I think you forgot the contentType: 'application/json' on ajax function.
It works for me.
try this instead of IEnumerable use array and place [FromUri] or [FromBody] which looks for values in the Uri or Body of the request.
[HttpPost]
public ActionResult H80Count([FromUri] H80SearchCriteria[] model)
{
do some stuff and return Json;
}
and dont forget to set the traditional ajax settings as true
$.ajax({
type: 'POST',
url: url,
data: data,
traditional: true
});

Categories

Resources