I am using jquery ajax to make a call to C# controller's method and here is the controllers method:
public ActionResult AddRegion(string pageIdIn, string fieldIdIn, RegionMV regionMv)
{
var fieldRegFormDataOutMv = batchLogic.AddRegion(Session.SessionID, pageIdIn, fieldIdIn, regionMv);
var json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(fieldRegFormDataOutMv);
return Json(json, JsonRequestBehavior.AllowGet);
}
Here is the ajax call code:
function AjaxWrapper(param, url, success, failure, deferred, args) {
return $.ajax({
type: "POST",
url: url,
data: param,
// contentType: "application/json; charset=utf-8",
//dataType: "json",
success: function (data, textStatus, jqXHR) {
success(data, args);
deferred.resolve();
},
error: function (jqXHR, textStatus, errorThrown) {
// //! call the function that will pop a div in the view to tell the user something went wrong - > failure(response);
failure(textStatus);
console.log(jqXHR);
deferred.reject();
},
cache: false
});
}
And here is the code that calls the ajax method:
function addRegion(pageId, fieldId, region) {
var param = { pageIdIn: pageId, fieldIdIn: fieldId, regionMv: region };
var deferred = $.Deferred();
showProgress();
AjaxWrapper(param, window.urlsList.addRegionUrl, updateView, showError, deferred).done(function () {
hideProgress();
});
return deferred.promise();
}
The problem is that on my computer(using Windows 7) the region json is being mapped to a RegionMV object correctly(with all properties and a correct bounding box), but on another computer(using Windows 10) the region's properties are mapped correctly except the bounding box.
Here is the class RegionMV:
public class RegionMV
{
// Index of the region in the parent page
public string Id { get; set; }
// Region type
public RegionType Type { get; set; }
// Region bounding box
public RectMV BoundingRect { get; set; }
// Region confidence as a specific field (determined by the 'Name' property)
public int FieldConfidence { get; set; }
// Region name (filled for regions assigned to specific fields or cells)
public string Name { get; set; }
// Region text content
public string Content { get; set; }
// Region text content filtered as specific field (determined by the 'Name' property) value
public string ContentFiltered { get; set; }
}
Any ideas why is that happening? Is it because of the different operational systems(I kind of doubt that, but still?) or because of something else?
EDIT!
Here is my RectMV class:
public class RectMV
{
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
}
And the Chrome Versions are the same on both machines.
Related
I am new to mvc and I am tring to use ajax to get and post data. Get is working fine but when I use post using the same ajax code while change it to post give me always error 400. I tried with many type of data sent and the action in the controller is empty to eleminate that the error occour there although i new 400 error is a bad request but I couldn't figure it out.
The code is as follow
async function SaveTheDay(url, data) {
if (data != null) {
$.ajax({
url: url,
type: 'POST',
dataType: "json",
data: data,
success: function (response) {
if (response) {
console.log("Ok");
} else {
console.log("not valid ");
}
},
error: function (req, status, error) {
console.log("error "+status+" "+error);
}
})//not null
}
}//SaveTheDay
the controller action is :
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SaveDay(InfoDay day)
{
return View("DayTrial");
}
and I call the function when the save button cliked as:
//define the object
var infoDay =
{
userId :userId,
date: TheDate.value ,
items :items ,
itemsAmount : itemsAmount,
itemsMealTime :itemsMealTime,
dailyConsumedkCal: dailyConsumedkCal,
dayTotal :"",
bloodData :"",
bloodSugarData :"",
sleepData :"",
indexData :"",
dayCost :0
}
SaveTheDay("/Days/SaveDay", infoDay);
here is the InfoDay class
public class InfoDay
{
public int userId { get;
set; }
public string date { get; set;
}
public string? items { get;
set; }
public string? itemsAmount {
get; set; }
public string? itemsMealTime {
get; set; }
public int? dailyConsumedkCal
{ get; set; }
public string? dayTotal {
get; set; }
public string? bloodData {
get; set; }
public string? bloodSugarData
{ get; set; }
public string? sleepData {
get; set; }
public string? indexData {
get; set; }
public int? dayCost { get;
set; } = 0;
}
The ValidateAntiForgeryToken attribute prevents 'Cross-site request forgery' attacks in your MVC application.
See https://learn.microsoft.com/..../security/anti-request-forgery?view=aspnetcore
Do not remove it.
To avoid the 400 error, you must pass the token with your POST request.
async function SaveTheDay(url, data) {
if (data != null) {
$.ajax({
url: url,
type: 'POST',
dataType: "json",
data: data,
beforeSend: function (xhr) {
xhr.setRequestHeader('RequestVerificationToken',
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (response) {
if (response) {
console.log("Ok");
} else {
console.log("not valid ");
}
},
error: function (req, status, error) {
console.log("error "+status+" "+error);
}
})//not null
}
}//SaveTheDay
Of course the hidden field with the token has to be present in the view.
The HTML Helper Html.AntiForgeryToken includes the token.
#Html.AntiForgeryToken()
If you use a form tag helper, the token is also included.
See https://learn.microsoft.com...?view=aspnetcore-6.0#the-form-tag-helper
Via the 'data' properie on a ajax post i want to send a parameter to the action method. All values in the parameter object get through except the decimal/double values. Why is this and what can i do about it?
I have tried to change the value to string and even int. And it gets through but it is important that it gets through as a decimal or double.
mapHub.client.requestForHelpInClient = function (requestDetails) {
$.ajax({
type: "POST",
url: '#Url.Action("RequestPartialView", "Supplier")',
data: requestDetails,
success: function (response) {
$("#Request").html(response);
},
error: function (error) {
console.log(error);
}
});
}
[HttpPost]
public ActionResult RequestPartialView(RequestDetails reqDetails)
{
RequestViewModel reqVm = new RequestViewModel() { requestDetails = reqDetails };
return PartialView("RequestPartialView",reqVm);
}
//This is the object i pass into requestForHelpInClient function that executes the ajax call
public class RequestDetails
{
public int CustomerId { get; set; }
public Customer Customer { get; set; }
public int NumberOfHours { get; set; }
public string TypeOfMachine { get; set; }
public List<Supplier> NearestSupplierList { get; set; }
}
public class Customer : MapClient
{
public int CustomerID { get; set; }
public string AspNetUserID { get; set; }
public string Name { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
every value gets through from the ajax call to the action method parameter excepts the latitude and longitude decimal values.
I get no error message. The value just says '0'
You need to stringify your object before posting
mapHub.client.requestForHelpInClient = function (requestDetails) {
$.ajax({
type: "POST",
url: '#Url.Action("RequestPartialView", "Supplier")',
data: JSON.stringify(requestDetails),
success: function (response) {
$("#Request").html(response);
},
error: function (error) {
console.log(error);
}
});
}
That should fix it
My ViewModel is:
public class CFUViewModel
{
public int RID { get; set; }
public int Order { get; set; }
public List<VCItem> VItems{ get; set; }
}
where VCItem is:
public class VCItem
{
public string Name{ get; set; }
public string Category { get; set; }
}
In my view, I am collecting the data from form elements. Thus,
$('#submit').click(function () {
console.log(gatherData());
transmitData(gatherData());
});
function gatherData() {
var vc = dataObject.getVCItems();
//This is a knockout function that gives an array of VCItems
var data = new Object();
data.RID = $('#rid').val();
data.VItems = vc;
return data;
};
function transmitData(dataToSend) {
$.ajax({
url: '../CFUDashboard/ReceiveData',
type: 'post',
dataType : 'json',
success: function (data) {
alert('success');
},
data: dataToSend
});
};
In the controller, I have:
[HttpPost]
public ActionResult ReceiveData(CFUViewModel viewModel)
{
//...
}
The problem is, though RID is ok, VItems list is not serialized. I suspect, the reason is, the array attached to the JS object is actually string (array wrapped in quotes). This is confirmed by the console.log(gatherData())
It is outputted as:
VItems : "[{"Name":"OPV3","Category":"FUGY"},{"Name":"OPV7","Category":"FUGX"}]"
What is the reason for not getting the list serialized? What am I missing?
Background:
In the view, we ask (via jquery and ajax) the controller for data from the database. The data is returned as Json, but for reasons unknown one part of the Json object is returned as null, even though it is properly set in the controller's JsonResult.
The Code:
The class to be returned as JsonResult
public class InData
{
public InData() { }
public AppsWithActions[] apps { get; set; }
public User[] users { get; set; }
public string timePeriod { get; set; }
public string startDate { get; set; }
public string endDate { get; set; }
public string dataType { get; set; }
}
The Problem is the string arrays actionIds and actionNames in the following class are null in the javascript, even though they have the correct values in the JsonResult:
public class AppsWithActions
{
public AppsWithActions() { }
public string id { get; set; }
public string name { get; set; }
public string[] actionIds { get; set; }
public string[] actionNames { get; set; }
}
The controller function that sets the InData and returns it to the javascript:
//Takes a goal setting, turns it to indata and returns a JsonResult
public JsonResult GetIndataFromGoalSettingId(SettingId settingId)
{
var id = ToGuid(settingId.idString);
GoalSetting setting = Session.Query<GoalSetting>()
.Where(x => x.Id == id)
.FirstOrDefault();
var indata = TransformGoalSettingToInData(setting);
return Json(new { returnvalue = indata }, JsonRequestBehavior.AllowGet);
}
The ajax call that returns everything correct, except the apps.actionIds and apps.actionNames
function getIndataFromGoalSettingId(settingId) {
if (settingId != null) {
settingIdIn = { "idString": settingId};
$.ajax({
type: "POST",
async: false,
traditional: true,
url: 'GetIndataFromGoalSettingId',
data: JSON.stringify(settingIdIn),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (result) {
//...
}
});
}
}
It should be said that we have successfully used the same kind of infrastructure for getting data and returning it as Json to the javascript before, but if anyone has a better suggestion feel free to spell it out!
I have an AJAX-enabled WCF service with the following signature:
[OperationContract]
[WebGet]
public JQGridContract GetJQGrid(int entityIndex)
And the following data contract:
[DataContract]
public class JQGridContract
{
[DataContract]
public class Row
{
[DataMember]
public int id { get; set; }
[DataMember]
public List<string> cell { get; set; }
public Row()
{
cell = new List<string>();
}
}
[DataMember]
public int page { get; set; }
[DataMember]
public int total { get; set; }
[DataMember]
public int records { get; set; }
[DataMember]
public List<Row> rows { get; set; }
public JQGridContract()
{
rows = new List<Row>();
}
}
Basically I need to change the postData of the client-side jqGrid to send 'entityIndex' to this service.
I've read how its supposed to function and from what I can tell this should work:
function loadGrid() {
$("#jqGrid").jqGrid({
postData: { entityIndex : function () { // modify the data posted to AJAX call here
return 6;
})
},
gridComplete: function () {
$("#jqGrid").setGridParam({ datatype: 'local' });
},
datatype: function (pdata) {
getData(pdata);
},
And here is the getData() function:
function getData(pdata) {
var params = new Object();
alert(pdata.entityIndex()); // this displays '6', correctly
params.entityIndex = pdata.entityIndex();
$.ajax(
{
type: "GET",
contentType: "application/json; charset=utf-8",
url: "AJAXService.svc/GetJQGrid",
data: JSON.stringify(params),
dataType: "json",
success: function (data, textStatus) {
if (textStatus == "success") {
var thegrid = $("#jqGrid")[0];
thegrid.addJSONData(data.d);
}
},
error: function (data, textStatus) {
alert('An error has occured retrieving data!');
}
});
Ive confirmed the following in Firebug:
1) The json params are correct : {"entityIndex":6}
2) The AJAX service returns JSON data to the grid, its just the wrong data
And here is the wierd part:
I logged the 'entityIndex' thats actually working inside the WCF operation -- and its ALWAYS coming up as 0?
Thanks.
I will not criticize the style of your program. I could write too many things about this. :-)
You current main problem could be solved with the usage JSON.stringify(pdata.entityIndex()) instead of JSON.stringify(params) or with the usage of another BodyStyle of the WFC method (see here for details)
I got it working, it is close to what Oleg said, just that you do not need to do JSON.stringify.
If you have WebMessageBodyStyle.WrappedRequest, this works:
data: { entityIndex: pdata.entityIndex() },
OR if you have no BodyStyle, this works:
data: { "entityIndex": pdata.entityIndex() },