I have an observable array Object that which is generated like this:
self.SelectedVariable = ko.observableArray();
self.VarUpdate = function (data) {
$.getJSON("/api/Variable/" + ko.toJS(data.VarID), ko.toJS(data.VarID), function (Result) {
for (var i = 0; i < Result.length; i++) {
element = Result[i];
self.SelectedVariable({ VariableID: ko.observable(element.VariableID), VariableDateLastUpdated: ko.observable(element.VariableDateLastUpdated), VariableName: ko.observable(element.VariableName), VariableDescription: ko.observable(element.VariableDescription), VariableValue: ko.observable(element.VariableValue), VariableType: ko.observable(element.VariableType) });
};
});
When I try to pass the SelectedVariable object to my WebAPI method using this AJAX call
$.ajax({
url: "/api/Variable?Del=0",
data: { vardata: ko.toJS(self.SelectedVariable) },
type: "PUT",
dataType: "JSON",
timeout: 10000,
success: function (Result) {
},
error: function (xhr, status) {
alert(status + " - " + xhr.responseText);
}
});
, all the related object shows null on all the fields.
I have tried almost every combination to get the SelectedVariable Object to parse correctly to my WebAPI method:
data: { vardata: ko.toJS(self.SelectedVariable) },
data: { vardata: ko.toJSON(self.SelectedVariable) },
data: { vardata: JSON.Stringify(self.SelectedVariable) },
data: { vardata: self.SelectedVariable },
and have tried to manually decrypt JSON object on WebAPI side using:
public void Put([FromUri] int Del, [FromBody]string vardata)
{
Variables vari = JsonConvert.DeserializeObject<Variables>(vardata);
var Item = (from c in TMIRE.Variables
where c.VariableID == vari.VariableID
select c).First();
if (Del == 0)
{
Item.VariableDateUpdated = DateTime.Now;
Item.VariableName = vari.VariableName;
Item.VariableDescription = vari.VariableDescription;
Item.VariableValue = vari.VariableValue;
Item.VariableType = vari.VariableType;
And It is still null value.
Any Advice would be greatly appreciated!
UPDATE
Changed my WebAPI method to reflect as follows:
public void Put([FromUri] int Del, IEnumerable<Variables> vardata)
{
var Item = (from c in TMIRE.Variables
where c.VariableID == vardata.Select(x => x.VariableID).First()
select c).First();
if (Del == 0)
{
Item.VariableDateUpdated = DateTime.Now;
vardata.Select(a => Item.VariableName = a.VariableName);
vardata.Select(b => Item.VariableDescription = b.VariableDescription);
vardata.Select(c => Item.VariableValue = c.VariableValue);
vardata.Select(d => Item.VariableType = d.VariableType);
}
and now the vardata object gets the value but all objects within are null
My Ajax method looks like this:
alert(ko.toJSON(self.SelectedVariable));
$.ajax({
url: "/api/Variable?Del=0",
contenttype: "application/x-www-form-urlencoded",
data: "=" + ko.toJSON(self.SelectedVariable()),
type: "PUT",
dataType: "JSON",
timeout: 10000,
success: function (Result) {
},
error: function (xhr, status) {
alert(status + " - " + xhr.responseText);
}
});
The alert gives me this response
The Variables Class
public class Variables
{
public int VariableID { get; set; }
public DateTime VarialbeDateLastUpdated { get; set; }
public string VariableName { get; set; }
public string VariableDescription { get; set; }
public string VariableValue { get; set; }
public string VariableType { get; set; }
}
Working Code
By using this Ajax call
$.ajax({
url: "/api/Variable?Del=0",
contenttype: "application/x-www-form-urlencoded",
data: "=" + ko.toJSON(self.SelectedVariable),
type: "PUT",
dataType: "JSON",
timeout: 10000,
success: function (Result) {
},
error: function (xhr, status) {
alert(status + " - " + xhr.responseText);
}
});
and then using Newtonsoft to deserialize the object on WebAPI using this method:
public void Put([FromUri] int Del, [FromBody]string vardata)
{
Variables vari = JsonConvert.DeserializeObject<Variables>(vardata.Substring(1, vardata.Length-2));
var Item = (from c in TMIRE.Variables
where c.VariableID == vari.VariableID
select c).First();
if (Del == 0)
{
Item.VariableDateUpdated = DateTime.Now;
Item.VariableName = vari.VariableName;
Item.VariableDescription = vari.VariableDescription;
Item.VariableValue = vari.VariableValue;
Item.VariableType = vari.VariableType;
}
else
{
Item.VariableDateUpdated = DateTime.Now;
Item.VariableActive = false;
}
TMIRE.SaveChanges();
}
I Got it to work
Try this...
public void Put([FromUri] int Del, IEnumerable<Variables> vardate){}
Since you're building a collection on the client self.SelectedVariable = ko.observableArray();, you will need the API to receive an IEnumerable.
In the Ajax call, I think it would be best to use:
data: { vardata: ko.toJSON(self.SelectedVariable) }
as this will give you a JSON representation of the collection.
Also, on the KO side, shouldn't you be pushing elements into the collection? self.SelectedVariable.push({...}); or you will end up with only the final result.
Change assignment to this:
self.SelectedVariable = ko.observableArray();
self.VarUpdate = function (data) {
$.getJSON("/api/Variable/" + ko.toJS(data.VarID), ko.toJS(data.VarID), function (Result) {
var selection = self.SelectedVariable;
for (var i = 0; i < Result.length; i++) {
var element = Result[i];
selection.push(element);
};
});
Then, Change the ajax method to convert to json:
$.ajax({
url: "/api/Variable?Del=0",
content-type: "application/x-www-form-urlencoded",
data: "=" + JSON.stringify(ko.toJSON(self.SelectedVariable)),
type: "PUT",
dataType: "JSON",
timeout: 10000,
success: function (Result) {
},
error: function (xhr, status) {
alert(status + " - " + xhr.responseText);
}
});
Also try removing [FromBody].
public void Put([FromUri] int Del, IEnumerable<Variables> vardata)
{
...
}
It looks like making the serialized objects in vardata as ko.observable objects is confusing mvc serialization for the parameters.
different data assignments to attempt:
data: "=" + JSON.stringify(ko.toJSON(self.SelectedVariable))
data: "=" + JSON.stringify(self.SelectedVariable())
data: "=" + self.SelectedVariable()
data: "=" + $.parseJSON(ko.toJSON(self.SelectedVariable))
What you're passing self.SelectedVariable isn't an array. Should you not be calling it just an observable? Otherwise, you need to be adding your results with self.SelectedVariable.push(resultObject).
By using this Ajax call
$.ajax({
url: "/api/Variable?Del=0",
contenttype: "application/x-www-form-urlencoded",
data: "=" + ko.toJSON(self.SelectedVariable),
type: "PUT",
dataType: "JSON",
timeout: 10000,
success: function (Result) {
},
error: function (xhr, status) {
alert(status + " - " + xhr.responseText);
}
});
and then using Newtonsoft to deserialize the object on WebAPI using this method:
public void Put([FromUri] int Del, [FromBody]string vardata)
{
Variables vari = JsonConvert.DeserializeObject<Variables>(vardata.Substring(1, vardata.Length-2));
var Item = (from c in TMIRE.Variables
where c.VariableID == vari.VariableID
select c).First();
if (Del == 0)
{
Item.VariableDateUpdated = DateTime.Now;
Item.VariableName = vari.VariableName;
Item.VariableDescription = vari.VariableDescription;
Item.VariableValue = vari.VariableValue;
Item.VariableType = vari.VariableType;
}
else
{
Item.VariableDateUpdated = DateTime.Now;
Item.VariableActive = false;
}
TMIRE.SaveChanges();
}
Related
Here is my controller. I am trying to pass the value through an if statement but it's not equalling (==) the string of "2019".
[HttpPost]
public ActionResult Extract(string[] response)
{
string statementQuery = "";
if (response!=null)
{
for (var i = 0; i < response.Length; i++)
{
if (response[i] == "2019")
{
statementQuery = "select statementPath from ClientStatements_Inventory where statementYear = '" + response[i] + "';";
}
}
}
Here is my ajax call. Is it something to do with the way it is sending to my controller? or my if statement?
$('#main-content-submit').click(function () {
var labelArray = [];
labelArray = $("input:checkbox:checked").map(function () {
return $(this).closest('label').text();
}).get();
console.log(labelArray);
event.preventDefault();
$.ajax({
type: 'POST',
url: '/Home/Extract',
data: JSON.stringify({ response:labelArray }),
contentType: 'application/json; charset=utf-8',
success: function (result) {
alert("Month and ear passed to controller");
},
error: function (err, result) {
alert("Error in Extract" + err.responseText);
},
});
return false;
});
Deserialization of a dynamic object that works fine in .NET Core 2.2, but does not work in .NET Core 3.1.
I'm using Newtonsoft.Json nuget package version v12.0.3. It's an ASP.NET Core MVC project.
public IActionResult Apply([FromBody]dynamic postData)
{
string serverPath = _hostingEnvironment.WebRootPath;
List<ModelData> list = new List<ModelData>();
foreach (var item in JsonConvert.DeserializeObject(postData))
{
list.Add(new ModelData
{
Key = item.Key,
Value = item.Value
});
}
}
I need help to fix it
Input data:
ValueKind = String : "[{'Key':'Table','Value':'admins'},{'Key':'MethodValue','Value':'Update'},{'Key':'Page','Value':'1'},{'Key':'Id','Value':'1'},{'Key':'ImgPath','Value':''},{'Key':'Id','Value':'1'},{'Key':'Login','Value':'admin'},{'Key':'Password','Value':'12345678999'}]"
It's what I see using debugger
ModelData output
public struct ModelData
{
public string Key { get; set; }
public string Value { get; set; }
}
Code from client page
function SendFormData(fileName) {
var jsonArr = "[{'Key':'Table','Value':'#ViewBag.Table'},{'Key':'MethodValue','Value':'#ViewBag.MethodValue'}," +
"{'Key':'Page','Value':'#ViewBag.Page'},{'Key':'Id','Value':'#ViewBag.Id'},";
jsonArr += "{'Key':'ImgPath','Value':'" + fileName + "'},";
var other_data = $("#ApplyForm").serializeArray();
$.each(other_data, function (_key, input) {
if (input.name === "Status") {
return true;
}
jsonArr += "{'Key':'" + input.name + "','Value':'" + input.value + "'},";
});
jsonArr = jsonArr.slice(0, -1);
jsonArr += "]";
$.ajax({
url: "/Admin/Apply",
type: "POST",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(jsonArr),
async: false,
success: function (returnUrl) {
AjaxLoad(returnUrl);
},
error: function () {
console.log("#Translations.UpsErrorMessage");
}
});
}
That seems client fail to send valid postData (no unique), and that is no need to stringify any string variable, except it is an array as following:
function SendFormData(fileName) {
var jsonArr = [{'Key':'Table',''Value':'#ViewBag.Table'},
{'Key':'MethodValue','Value':'#ViewBag.MethodValue'},
{'Key':'Page','Value':'#ViewBag.Page'},
{'Key':'ImgPath','Value':fileName}],
other_data = $("#ApplyForm").serializeArray();
$.each(other_data, function (_key, input) {
if (input.name === "Status") {
return true;
}
jsonArr.push({Key: input.name, Value: input.value});
});
$.ajax({
url: "/Admin/Apply",
type: "POST",
contentType: 'application/json; charset=utf-8',
data: {postData:JSON.stringify(jsonArr)},
async: false,
success: function (returnUrl) {
AjaxLoad(returnUrl);
},
error: function () {
console.log("#Translations.UpsErrorMessage");
}
});
}
I've a simple issue but it got complicated. I am trying to pass an array of object using jQuery and in the back-end, I am using C# to get the list. So this is what I've tried so far:
jQuery:
$('#btnStrickOff').on('click', function () {
var formData = new FormData();
debugger;
var rowindexes = $('#jqxgrid').jqxGrid('getselectedrowindexes');
for (var i = 0; i < rowindexes.length; i++) {
var row = $('#jqxgrid').jqxGrid('getrowdata', rowindexes[i]);
formData.append('strData[' + i + '].empno', row.empno);
formData.append('strData[' + i + '].Name', row.Name);
formData.append('strData[' + i + '].Des', row.Des);
formData.append('strData[' + i + '].Dept', row.Dept);
formData.append('strData[' + i + '].Section', row.Section);
formData.append('strData[' + i + '].Emp_type', row.Emp_type);
formData.append('strData[' + i + '].LateAtt', row.LateAtt);
formData.append('strData[' + i + '].Diff', row.Diff);
}
var url = '#Url.Action("InsertStrikeOff")';
debugger;
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: JSON.stringify({ 'things': formData }),
contentType: false,
processData: false,
async: false,
success: function (data) {
alert("Updated. - "+data);
}
});
});
So the idea is: There is a table and each row has a CheckBox associated with it. Whenever user checks a row or multiple, it should have the row data in an Array and iterate through, then passes to the C# controller in the Ajax call. Here is the C# code section:
C#:
public JsonResult InsertStrikeOff(List<DailyStrikeOffBO> things)
{
DateTime strikeDate = DateTime.Now;
var value = (dynamic)null;
foreach (var item in things)
{
bool chk = Facede.StrikeOff.CheckStrikeOff(item.empno);
if (chk == false)
{
bool aStrikeOffBo = Facede.StrikeOff.InserstrikeOffLst2(item.empno, item.Name, item.LateAtt, strikeDate, item.remarks);
value = "<div style='color:green;'>Striked-off request sent!</div>";
}
else
{
value = "<div style='color:red;'>Already striked off!</div>";
}
}
return Json(value, JsonRequestBehavior.AllowGet);
}
Unfortunately, I am getting this error every time when it calls the C# controller though I am quite sure I am doing the right thing - Object reference not set to an instance of an object. Anything that I missed here?
Update 1: Model
public class DailyStrikeOffBO
{
public string empno { get; set; }
public string Name { get; set; }
public string Des { get; set; }
public string Dept { get; set; }
public string Section { get; set; }
public string Emp_type { get; set; }
public string Diff { get; set; }
public string LateAtt { get; set; }
}
Update 2:
You cannot post an object containing FormData - you need to send the actual FormData object. In addition your name do not match the model you are posting to, which is a collection, not an object containing a collection.
Assuming DailyStrikeOffBO contains properties empno, Name,Des` etc, then you need to append the name/value pairs as
formData.append('[' + i + '].empno', row.empno);
formData.append('[' + i + '].Name', row.Name);
formData.append('[' + i + '].Des', row.Des);
.... // etc
and then modify the ajax option to
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: formData , // modify
contentType: false,
processData: false,
async: false,
success: function (data) {
alert("Updated. - "+data);
}
});
for (a = 0; a < rowindexes.length; a++) {
var row = $('#jqxgrid').jqxGrid('getrowdata', rowindexes[i]);
var model = {
empno : row.empno,
Name: row.Name,
Des: row.Des,
Dept: row.Dept,
Section: row.Section,
Emp_type: row.Emp_type,
Diff: row.Diff,
LateAtt: row.LateAtt
};
data.push(model);
}
var modelString = JSON.stringify(data);
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: modelString ,
contentType: "application/json; charset=utf-8",
processData: false,
success: function (data) {
alert("Updated. - "+data);
}
});
Instead of using FormData try using json object.
The way you are passing data thru ajax ( data: JSON.stringify({ 'things': formData }), ) that is also not correct.
Try the above code, let me know how it goes.
I am trying to fetch company data based on company id through ajax and fill the related textboxes with the received data. Company id is selected through ajax autocomplete. The code was working fine two days back and suddenly it started generating an error for only first two entries of autocomplete and for rest it is working fine. Can anyone point out the mistake in this. Thank you.
Error Details: "Message":"A circular reference was detected while serializing an object of type \u0027System.Data.Entity.DynamicProxies.Company_81625299B5B4D7A3375D55E48BE84921728B8D48335366DF8CA6844A8D10FF5D\u0027.","StackTrace":" at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)\r\n.
Below is my code:
function setCompanyData(pageurl, txtboxid, txtResultid) {
var temp = true;
var searchTbox = $jq14("[id$=" + txtboxid + "]");
var resultTbox = $jq14("[id$=" + txtResultid + "]");
searchTbox.autocomplete({
source: function (request, response) {
$jq14.ajax({
url: pageurl,
data: "{ 'SearchText': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function (item) {
return {
label: item.split('*')[0],
val: item.split('*')[1]
}
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
autoSelect: true,
autoFocus: true,
select: function (e, i) {
// e.preventDefault();
searchTbox.val(i.item.label);
resultTbox.val(i.item.val).trigger('change');
temp = true;
// return false;
},
change: function (e, i) {
var cId = resultTbox.val();
if (isEmptyOrSpaces(cId)) {
// error
cId = 0;
searchTbox.val("").trigger('');
}
if (isEmptyOrSpaces(searchTbox.val())) {
// error
cId = 0;
resultTbox.val("").trigger('change');
}
getCompanyDetails(cId);
},
minLength: 0
}).focus(function () {
if (temp) {
$jq14(this).autocomplete("search", "");
temp = false;
}
});
searchTbox.autocomplete("widget").addClass("fixedHeight");}
function getCompanyDetails(cid) {
$jq14.ajax({
url: "/sw/adm/update-delete-company.aspx/GetCompanyData",
data: "{ 'cId': '" + cid + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
beforeSend: function () {
$('#loader').show();
},
complete: function () {
$('#loader').hide();
$("#messageBox").hide().slideDown();
setTimeout(function () {
$("#messageBox").fadeOut();
}, 5000);
},
success: function (result) {
$jq14('#cphMainLeft_txtAddress').val(result.d.CompanyAddress);
$jq14('#cphMainLeft_txtCountry').val(result.d.CompanyCountry);
$jq14('#cphMainLeft_txtCity').val(result.d.CompanyCity);
$jq14('#cphMainLeft_txtNewCompanyName').val(result.d.CompanyName);
$jq14('#cphMainLeft_txtEmail').val(result.d.CompanyEmail);
$jq14('#cphMainLeft_txtPanNo').val(result.d.CompanyPAN);
$jq14('#cphMainLeft_txtTinNo').val(result.d.CompanyTIN);
$jq14('#cphMainLeft_txtPhone').val(result.d.CompanyPhone);
$jq14('#cphMainLeft_txtPincode').val(result.d.CompanyPincode);
$jq14('#cphMainLeft_hfTxtCountry').val(result.d.CompanyCountry);
$jq14("#cphMainLeft_ddlCompanyType").val(result.d.CompanyType);
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
}
C# Webmethod goes like:
[WebMethod]
public static Company GetCompanyData(int cId)
{
Entities db = new Entities();
var companyRecord = (from cmp in db.Companies
where cmp.CompanyId == cId
select cmp).SingleOrDefault();
if (companyRecord != null)
return companyRecord;
else
return new Company();
}
Thank you Ashokkumar M. Prajapati for providing the hint.
Instead of returning Company object from [WebMethod], I have converted the company object to Json string in code behind and returned it.
Here is my WebMethod:
[WebMethod]
public static string GetCompanyData(int cId)
{
Entities db = new Entities();
var companyRecord = (from cmp in db.Companies
where cmp.CompanyId == cId
select cmp).SingleOrDefault();
if (companyRecord == null)
companyRecord = new Company();
string s = string.Empty;
s = JsonConvert.SerializeObject(companyRecord,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
return s;
}
Then I updated the success method of getCompanyDetails(cid) to:
success: function (result) {
res = JSON.parse(result.d);
$jq14('#cphMainLeft_txtAddress').val(res['CompanyAddress']);
$jq14('#cphMainLeft_txtCountry').val(res['CompanyCountry']);
$jq14('#cphMainLeft_txtCity').val(res['CompanyCity']);
$jq14('#cphMainLeft_txtNewCompanyName').val(res['CompanyName']);
$jq14('#cphMainLeft_txtEmail').val(res['CompanyEmail']);
$jq14('#cphMainLeft_txtPanNo').val(res['CompanyPAN']);
$jq14('#cphMainLeft_txtTinNo').val(res['CompanyTIN']);
$jq14('#cphMainLeft_txtPhone').val(res['CompanyPhone']);
$jq14('#cphMainLeft_txtPincode').val(res['CompanyPincode']);
$jq14('#cphMainLeft_hfTxtCountry').val(res['CompanyCountry']);
$jq14("#cphMainLeft_ddlCompanyType").val(res['CompanyType']);
}
and it worked wonderfully. Thanks again.
I have a need to call a method on my controller to return a complex type using the JQuery.Ajax method.
function CallMethodTest(Id) {
//alert(Id);
$.ajax({
type: 'POST',
url: '/MyController/MyMethod',
dataType: "json",
contentType: "application/json; charset=utf-8",
//data: "{'Id': '" + Id + "'}",
success: function (data) {
alert(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
[System.Web.Services.WebMethod]
public string MyMethod()
{
return "ABC"; // Gives me the error on the first alert of "200" and the second alert "Syntax Error: Invalid Character"
return "1"; // Works fine
}
As the code explains, if I return an integer (as a string) the return works and I alert "1", however, If I try and return any alpha characters I get the alerts shown in the comments of MyMethod.
From your code, it looks as though you are returning the value from your Controller url: "/MyController/MyMethod"
If you are returning the value from your controller, then get rid of the [System.Web.Services.WebMethod] code and replace it with this ActionResult
[HttpPost]
public ActionResult MyMethod(){
return Json("ABC");
}
Also, if you are ever going to call a method in your controller via GET then use
public ActionResult MyMethod(){
return Json("ABC", JsonRequestBehavior.AllowGet);
}
In View You use the following code,
function ItemCapacity() {
$.ajax({
type: "POST",
url: '#Url.Action("ItemCapacityList", "SalesDept")',
data: { 'itemCategoryId': itemCategoryIds },
dataType: 'json',
cache: false,
success: function (data) {
var capacityCounter = 0;
var capacitySelected = "";
for (var i = 0; i < rowsCount; i++) {
var tr = $("#gvSpareSetItemsDetails tbody tr:eq(" + i + ")");
var categoryId = $(tr).find('td:eq(5)').text();
var isSelectOrNot = $(tr).find('td:eq(1)').find('select');
if (isSelectOrNot.is('select')) {
$.map(data, function (item) {
if (categoryId == item.ItemCategoryID) {
isSelectOrNot.get(0).options[isSelectOrNot.get(0).options.length] = new Option(item.CapacityDescription, item.ItemCapacityID);
capacityCounter = capacityCounter + 1;
capacitySelected = item.ItemCapacityID;
}
});
if (capacityCounter == 1) {
isSelectOrNot.val(capacitySelected);
}
capacityCounter = 0;
capacitySelected = "";
}
}
},
error: function () { alert("Connection Failed. Please Try Again"); }
});
}
}
In the Controller Use the following Code,
public JsonResult ItemCapacityList(string itemCategoryId)
{
List<ItemCapacity> lsItemCapacity = new List<ItemCapacity>();
string[] itemCategory = itemCategoryId.Split('#');
int itemCategoryLength = itemCategory.Length, rowCount = 0;
string itemCategoryIds = string.Empty;
for (rowCount = 0; rowCount < itemCategoryLength; rowCount++)
{
itemCategoryIds += "'" + itemCategory[rowCount].Trim() + "',";
}
itemCategoryIds = itemCategoryIds.Remove(itemCategoryIds.Length - 1);
lsItemCapacity = salesDal.ReadItemCapacityByCategoryId(itemCategoryIds);
return new JsonResult { Data = lsItemCapacity };
}