POST 500 error when sending JSON stringified javascript object to controller - javascript

I'm currently working on a ASP.net Web application with the MVC pattern. I have set up a page where people can add items to a gridstack section and drag them around (Gridstack is a plugin to create draggable boxes/objects). My goal is to send the final coordinates of these boxes to my controller:
function saveData() {
var pagePositions = [];
// Fill our array
$('.grid-stack-item.ui-draggable').each(function () {
var $this = $(this);
pagePositions.push({
x: $this.attr('data-gs-x'),
y: $this.attr('data-gs-y'),
w: $this.attr('data-gs-width'),
h: $this.attr('data-gs-height'),
content: $('.grid-stack-item-content', $this).html()
});
});
// Convert array to object
var pagePosData = toObject(pagePositions);
alert(pagePosData);
$.ajax({
type: "POST",
url: "savePage",
data: { positions: JSON.stringify(pagePosData) }
});
} function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
if (arr[i] !== undefined) rv[i] = arr[i];
return rv;
}
The code above fills the attributes of the given html elements and puts them into an array. I assumed, according to several topics on the internet, that sending the array was causing trouble so i inserted a function that converts the array to an javascript object (key value pairs). I send them to my controller with an AJAX call which results in a error code 500:
[HttpPost]
public string savePage(string positions)
{
//some code
var json = positions;
var test = "";
CreatePagemodelJson obj = new JavaScriptSerializer().Deserialize<CreatePagemodelJson>(positions.ToString());
//var jsonObject = JsonConvert.DeserializeObject<CreatePagemodel>(positionsJson.ToString());
return "";
}
I set up breakpoints inside the controller to read the value i get from the parameter positions, but it doesn't even get to that point. I tried setting up models for the Json file but the problem here is that the post calls return a dynamic json format.
Update:
I managed to get it working with below posts. With below structure, i get the results as an array according to my model.
function saveData() {
var pagePositions = [];
// Fill our array
$('.grid-stack-item.ui-draggable').each(function () {
var $this = $(this);
pagePositions.push({
x: $this.attr('data-gs-x'),
y: $this.attr('data-gs-y'),
w: $this.attr('data-gs-width'),
h: $this.attr('data-gs-height'),
content: $('.grid-stack-item-content', $this).html()
});
});
alert(pagePositions);
$.ajax({
type: "POST",
url: "savePage",
contentType: 'application/json',
data: JSON.stringify(pagePositions)
});
}
public class Position
{
public string x { get; set; }
public string y { get; set; }
public string w { get; set; }
public string h { get; set; }
public string content { get; set; }
}
[HttpPost]
public ActionResult savePage(IEnumerable<Position> positions)
{
//some code
return View("SomeView");
}
The parameter positions succesfully returns the array of pagePositions send with the post:
I tried sending the data without the JSON.stringify(pagePositions) and ContentType: 'application/json' option but i got a null return in my parameter on the controller.

There a number of things to point out here.
With your current question.
The data you are sending isn't a string. data: { positions: JSON.stringify(pagePosData) } is creating a JavaScript object with a property of positions whose value is the serialized version of your object.
You should be able to create a c# class and accept that as your controller methods parameter and get closer to the results you are expecting. That would look as follows:
public class Foo
{
public string Positions { get; set; }
}
public string savePage(Foo positions)
Alternatively you could update your method to get the request body as a string as shown in this SO answer
More importantly though, it would seem as though you came across some misinformation. There shouldn't be any issue passing an array back to your controller. Again, you will need a c# class that models your expected data type(s). You don't list those in your question, so it is hard to say for sure how you need to update your code, but I would suggest something more like the following:
function saveData() {
var pagePositions = [];
// Fill our array
$('.grid-stack-item.ui-draggable').each(function () {
var $this = $(this);
pagePositions.push({
x: $this.attr('data-gs-x'),
y: $this.attr('data-gs-y'),
w: $this.attr('data-gs-width'),
h: $this.attr('data-gs-height'),
content: $('.grid-stack-item-content', $this).html()
});
});
$.ajax({
type: "POST",
url: "savePage",
data: JSON.stringify(pagePositions),
contentType: "application/json"
});
}
public class Position
{
public int X { get; set; }
public int Y { get; set; }
public int W { get; set; }
public int H { get; set; }
public string Content { get; set; }
}
[HttpPost]
public string savePage(Position[] positions)
{
//some code
return "";
}
If this doesn't work, please provide more details about what doesn't work, what error you are receiving and what version of asp.net mvc you are using.

Related

Object array in FormData passing 0 objects to controller

I'm making an ajax call to the controller passing the FormData(), which has an array of objects along with few other properties. In my controller, the list array which I'm passing seems to have 0 elements. Please help!
Script in cshtml view -
var _getFormDataToJson = function () {
var applyDetail = [];
$(_tb).find('tbody tr').each(function (i, v) {
var trans = {
effectiveDate: $(this).find('.effectiveDate').val(),
amount: $(this).find('.amount').val(),
empLeaveHdID: $('#tx-leaveHdID').val(),
//attachmentUrl: $(this).find('.leaveAttachment')[0].files[0]
}
applyDetail.push(trans);
});
var formObj = new FormData();
formObj.append('remark', $('#tx-remark').val());
formObj.append('leaveAppType', $('#hdnLeaveAppType').val());
formObj.append('applyDetail', applyDetail); //this collection has 0 items in controller
return formObj;
}
var _sumbitForm = function () {
var formData2 = _getFormDataToJson();
$.ajax({
url: '#Url.Action("ApplyLeave", "Leave")',
type: 'POST',
processData: false,
contentType: false,
data: formData2,
//data: { data: formData2 },
success: function (data) {
if (data.success) {
_myToastr.success(data.msg[0], true, function () {
location.reload();
});
$(_modal).modal('close');
}
else {
_myToastr.error(data.msg[0]);
}
},
complete: function () {
}
});
}
Controller -
[HttpPost]
public JsonResult ApplyLeave(Hr_LeaveApplyHd data)
{
foreach (var detail in data.applyDetail) //applyDetail count is 0 here
{
//to DO:
}
return new JsonResult();
}
EDIT:
Hr_LeaveApplyHd model -
public class Hr_LeaveApplyHd
{
public Hr_LeaveApplyHd()
{
applyDetail = new List<ApplyDetail>();
}
[Key]
public int applyID { get; set; }
public string remark { get; set; }
public virtual List<ApplyDetail> applyDetail { get; set; }
public LeaveAppType leaveAppType { get; set; }
}
applyDetail model -
public class ApplyDetail
{
[Key]
public int applyDetialID { get; set; }
public DateTime effectiveDate { get; set; }
public decimal amount { get; set; }
public int empLeaveHdID { get; set; }
}
You cannot append arrays and/or complex objects to FormData. You need to append name/value pairs for each property of ApplyDetail and for each item in the collection, and with indexers, for example
formObj .append('applyDetail[0].effectiveDate', '09/19/2017');
which you could do in your $.each loop, for example
var formObj = new FormData();
formObj.append('remark', $('#tx-remark').val());
formObj.append('leaveAppType', $('#hdnLeaveAppType').val());
$(_tb).find('tbody tr').each(function (i, v) {
var name = 'applyDetail[' + i + '].effectiveDate';
var value = $(this).find('.effectiveDate').val();
formObj.append(name, value);
... // ditto for other properties
});
However, if you have generated your form correctly using the strongly typed HtmlHelper methods, including generating the controls for the collection property using a for loop of EditorTemplate for typeof ApplyDetail so they have the correct name attributes to match your model, then all you need is
var formObj = new FormData($('form').get(0));
which will correctly serialize all the form controls

Ajax with formData dose not bind child's array of objects in asp.net controller

Hi I am trying to send files and some object in ajax call, using form data
here is my ajax call
$.ajax({
type: "POST",
url: "/Post/SharePost",
processData: false,
contentType: false,
headers: getAjaxHeaderWithToken(),
dataType: "json",
data: getDataToPost(),
});
here is my getDataToPost() method
function getDataToPost() {
var dataToPost = new FormData();
for (var i = 0; i < savedPictures.length; i++) {
var savedPictureToPost = { PictureId: savedPictures[i].PictureId};
dataToPost.append("vm.SavedPictures[" + i + "]", JSON.stringify( savedPictureToPost));
}
}
here is my controller
[HttpPost]
[ValidateAntiForgeryTokenOnAllPosts]
public ActionResult SharePost(SharePostVM vm, IEnumerable<HttpPostedFileBase> unsavedPictures)
{
}
and here is my SharePostVM
public class SharePostVM : BasePostVM
{
public SharePostCategories SharePostCategories { get; set; }
[Required]
public decimal? Price { get; set; }
[Required]
[Display(Name = "Available Date")]
public string DateAvailableFrom { get; set; }
public IEnumerable<PictureVM> SavedPictures { get; set; }
}
As you can see in my controller, I need to send files as well, but I just exclude the method for making it simple. Basically, I need to send files and object with an array of object. I can bind files and the property of SharePostVM like price and DateAvailableFrom by appending like dataToPost.append("vm", "priceValue"), but I can't bind the SavedPictures in SharePostVM. How can I bind them? I know I can retrieve from Request on server side but I just want to know if i can bind them. I have also tried without JSON.stringfy() but it still does not work..
Thanks guys
Try like this:
var pictureId = savedPictures[i].PictureId;
dataToPost.append("SavedPictures[" + i + "].PictureId", pictureId);
// ... and so on if you want to bind other properties than PictureId
Also in the getDataToPost function that you have shown in your question there's no return statement but I guess this is just a typo here and in your actual code the function returns a value.

Sending Latitude and Longitude double values to MVC Controller but getting NULL values

I have hard coded the latitude and longitude values but still i'm getting null values in controller, I have tried many solutions but couldn't get it to work. I think there is a mismatch between my javascript object "mydata" and my MVC object Table.
Javascript Code
<script>
map.setContextMenu({
control: 'map',
options: [{
title: 'Click to add marker',
name: 'add_marker',
action: function (e) {
$("#markerform").show();
var latitude = 31.555;
var longitude = 74.333;
var m = $('#m').val();
var n = $('#n').val();
var o = $('#o').val();
var ad = $('#ad').val();
var ph = $('#ph').val();
var w = $('#w').val();
var fb = $('#fb').val();
var l = "RAO";
var mydata = {
lat: latitude,
lng: longitude,
marker: m,
name: n,
offer: o,
address: ad,
phn: ph,
website: w,
fbpage: fb,
logo: l
};
function SaveMarker() {
$.ajax({
type: 'POST',
data: mydata,
url: "/Home/AddMarker",
// dataType: 'json',
// data: JSON.stringify(data),
success: function () {
alert('suc');
},
error: function (args) {
alert('error');
}
});
}
}
}
]
});
</script>
In controller
[HttpPost]
public ActionResult AddMarker(Table t){
//Some Code
return View("../Home/Index");
}
My Table Class
public partial class Table
{
public int Id { get; set; }
public Nullable<double> lat { get; set; }
public Nullable<double> lng { get; set; }
public string marker { get; set; }
public string name { get; set; }
public string offer { get; set; }
public string address { get; set; }
public string phn { get; set; }
public string website { get; set; }
public string fbpage { get; set; }
public string logo { get; set; }
}
Don't stringify your JSON data. You're posting a string at that point, not JSON or a set of name-value pairs. MVC attempts to bind the string itself as Table and of course fails, because there's no conversion from string to your Table class. Instead, just pass data itself as the data param for your AJAX request. That also assumes that the JavaScript object represented by data mirrors your C# Table class. Otherwise, you'll still have issues with binding. In other words, if your Table class has a property Latitude, then your JavaScript object would need to have a member named Latitude or latitude (casing doesn't matter).
Thanks for the help #Chris Pratt, i finally found the solution. i was calling the function SaveMarker from a form that is why the function was not reading the latitude and longitude values. Now i am getting the lat lng values in a separate funtion using a separate ajax call, everything is working smoothly now :).

How to call page method with a parameter through in a javascript event?

I have method like this in my .cs :
[System.Web.Services.WebMethod]
public static void GetServiceInformation(IInfo x) //IInfo is an interface
{
x.l_power = true;
x.lb_InboxCount = UserTrans.GetInbox(int.Parse(emp_num), 0);
}
Now i want to call this method through a javascript method as a page method but it doesn't work .
<script type ="text/javascript">
function GetInfo() {
PageMethods.GetServiceInformation(this);
}
window.onload = setTimeout("GetInfo()", 3000);
</script>
<telerik:RadScriptManager ID="RadScriptManager1" runat="server" EnablePageMethods="true">
</telerik:RadScriptManager>
My .cs :
public partial class AppMaster : Log, IInfo //My page
{
public string Inbox
{
get
{
return hpl_Inbox.NavigateUrl;
}
set
{
hpl_Inbox.NavigateUrl = value;
}
}
public string Draft
{
get
{
return hpl_Draft.NavigateUrl;
}
set
{
hpl_Draft.NavigateUrl = value;
}
}
public string New
{
get
{
return hpl_New.NavigateUrl;
}
set
{
hpl_New.NavigateUrl = value;
}
}
public string Approved
{
get
{
return hpl_Approved.NavigateUrl;
}
set
{
hpl_Approved.NavigateUrl = value;
}
}
//------- etc
}
My interface :
public interface IInfo
{
string Inbox { get; set; }
string Draft { get; set; }
string New { get; set; }
string Approved { get; set; }
string archive { get; set; }
string search { get; set; }
string cand { get; set; }
string pri { get; set; }
string power { get; set; }
string admin { get; set; }
string help { get; set; }
bool l_cand { get; set; }
bool l_pri { get; set; }
bool l_power { get; set; }
bool l_admin { get; set; }
string lb_ApprovedCount { get; set; }
string lb_InboxCount { get; set; }
string lb_archive { get; set; }
string lb_DraftCount { get; set; }
}
function GetServiceInformation(x) {
$.ajax({
type: "POST",
url: "page.aspx/GetServiceInformation",
data: "{'x':'" + x + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: on_sucess,
error: on_error
});
function on_sucess(data, status) {
alert(data);
}
function on_error(request, status, error) {
alert(error);
}
}
Sorry, if it doesn't work
Answer Edit Based On Chat Discussion
First, thanks for clarifying your question. It was bit hard to understand the problem you were trying to solve. The reason? Because your code wasn't clear enough and that usually happens when there are design issues. That's effectively what your facing here a bit of a design issue. First, I'll point out some mistakes...
In this javascript function...
function GetInfo() {
PageMethods.GetServiceInformation(this);
}
this is NOT an instance of your page. So there's no use to make your page implement an interface...
public partial class AppMaster : Log, IInfo{}
and expect that a javascript call would page an instance of System.Web.UI.Page to your class (not to mention an implementation of the IInfo interface). You can blindly ditch this approach because it's a permanent design issue and it's not even going to work.
Now, if what you want is to serve the page, then do some further processing and finally send the results of this processing back to the client asynchronously using javascript/ajax you have a couple of approaches here:
Using SignalR which is my favourite approach (but you already stated your solution doesn't meet the requirements to use SignalR)
Using jQuery ajax which is also a very valid approach
Now, I'll explain the second approach
Using jQuery Ajax
Simply render the page as you would normally do in ASP.NET. Then on the client-side, when the page loads, make an ajax request to start processing the information you want to display. You can start the request as soon as the page loads to make the processing on the server
$(function(){
$.ajax({
type: 'POST',
url: 'AppMaster.aspx/GetServiceInformation',
data: "{}",
contentType: 'application/json;charset=utf-8',
dataType: 'json',
success: function(d) {
//load data received
},
error: function() {
//process the error
}
});
});
In the success handler you need to load the values received from the ajax call on your web controls. Then change your IInfo interface to a concrete object in a separate code file. But, remember that this class should NOT hold any references whatsoever to your web controls
public class JSInfo
{
string Inbox { get; set; }
string Draft { get; set; }
string New { get; set; }
string Approved { get; set; }
string archive { get; set; }
string search { get; set; }
string cand { get; set; }
string pri { get; set; }
string power { get; set; }
string admin { get; set; }
string help { get; set; }
bool l_cand { get; set; }
bool l_pri { get; set; }
bool l_power { get; set; }
bool l_admin { get; set; }
string lb_ApprovedCount { get; set; }
string lb_InboxCount { get; set; }
string lb_archive { get; set; }
string lb_DraftCount { get; set; }
}
then change your page method to...
[System.Web.Services.WebMethod]
public static JSInfo GetServiceInformation()
{
//you need to get the emp_num from session
//construct the JSInfo object
JSInfo info = new JSInfo();
//get the data from the database
var data = UserTrans.GetInbox(int.Parse(emp_num), 0);
//set the properties of the JSInfo...similar to the line below for each property...Draft, New, Approved, etc
info.Inbox = data.Inbox;
//return the object to the client
return info;
}
Notice that you need to get the emp_num value from Session since you stated in the chat discussion that this value comes from a Session variable. Now, going back to the success handler of your jQuery ajax call which executes soon after the response is received back from the server. You will receive a json object in the handler parameter d with the properties of the JSInfo class that you just sent from the server. Then you set the controls on the page...
success: function(d) {
$('#id_inbox_control').val(d.Inbox);
$('#id_draft_control').val(d.Draft);
$('#id_new_control').val(d.New);
//and keep doing the same for the rest of the controls
},
That should be a neater solution. Of coure, I cannot cover every single details here. But for sure you will get the idea. If not, let me know if I need to expand on something.
If your page implements the interface, you don't have to pass it! In your c# code write:
this.l_power=true;
If you need to pass values from JavaScript to page method, define each property as a parameter and pass values to the page method:
[System.Web.Services.WebMethod]
public static string GetServiceInformation(int value1, string value2)
{
l_power = value1;
something = value2;
return "some string to indicate the result of call";
}
And:
<script type ="text/javascript">
var v1 = 15;
var v2 = "some value";
function GetInfo() {
PageMethods.GetServiceInformation(v1, v2, success, fail);
}
window.onload = setTimeout("GetInfo()", 3000);
</script>
in which success and fail are the names of two JS functions that will be called after the request is completed. Note that a page method can return a string value to inform the client about what happened on the server.
I can only think of one method.
You should somehow marshal the this object, and send it as parameter. I mean you should write a method that marshalls an object to equivalent json or xml, and POST that to your server.
I believe you can do it as you did above only through a clean API and compiler tool between C# and javascript to implement RPC just like GWT was written for java and javascript.
Can you do a little test?
Declare a public class JSInfo: IInfo{} in your page code, and in your web method declare that parameter of yours as JSInfo.
As JSInfo implements IInfo, your program logic can work with it without any problem.
Just to let you know, your code does not work because you cannot serialize interfaces as they
are not concrete types, if you think about it, interfaces have no real correlation in XML schema. There's no way to represent the data. Base classes will work however.
If you fill bad in declaring the JSInfo in the asp.net page class, then create a class called
WebMethodsHelper and declare your JavaScript WebMethod Interfaces (Adaptors) there.
public class JSInfo: IInfo{
private ControlsCollection controls;
public JSInfo(ControlsCollection constrols){
this.controls = controls
FillObjects();
}
private void FillObjects(){
//iterate through controls and extract you data to you
//class properties/fields
}
public void Update(ControlsCollection controls){
this.controls=controls;
FillObjects();
}
public void Update(JSInfo info, ControlsCollection controls){
this.controls=controls;
//populate your object based on info
//then extract data from page controls
FillObjects();
}
}
public class MyPage: System.Web.UI.Page{
protected void Page_Load(object sender, EventArgs e){
if(!IsPostBack && Session["info_obj"])
Session["info_obj"] = new JSInfo(this.Controls);
}
[System.Web.Services.WebMethod]
public static string GetServiceInformation(JSInfo data)
{
JSInfo info = new JSInfo(this.Controls);
info.Update(data);
//or if you stored the info in the session
JSInfo info = (JSInfo)Session["info_obj"];
info.Update(this.Controls, data);
}
}
The JSInfo is just to give your IInfo interface some structure so it can be serialized.
From JavaScript you should be able to call you page method like this:
<script type ="text/javascript">
function GetInfo() {
var info = new JSInfo();
info.PropertyXPTO="something";
PageMethods.GetServiceInformation(info, onSuccess, onError);
}
function onSuccess(result) {
alert(result);
}
function onError(result) {
alert('error: ' + result);
}
window.addEventListener("load", function(){
setTimeout("GetInfo()", 10 * 1000);
}, false);
</script>
Not that you should have a ScriptManager at the top of your page
<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server" />
The ScriptManager is responsible for giving you the PageMethods class in the JavaScript, along
with other things.
Also, confirm the following:
The page method must have the System.Web.Services.WebMethod attribute. [WebMethod]
The page method must be public. [WebMethod] public ...
The page method must be static. [WebMethod] public static ...
The page method must be defined on the page (either inline or in the code-behind). It cannot be defined in a control, master page, or base page.
The ASP.NET AJAX Script Manager must have EnablePageMethods set to true.
function GetServiceInformation(x) {
$.ajax({
type: "POST",
url: "page.aspx/GetServiceInformation",
data: x, //Attention: there is no {}
contentType: "application/json; charset=utf-8",
dataType: "json",
success: on_sucess,
error: on_error
});
function on_sucess(data, status) {
alert(data);
}
function on_error(request, status, error) {
alert(error);
}
}
And then
<script type ="text/javascript">
function GetInfo() {
var myInfo = {
Inbox: "",
Draft: "",
New: "",
l_cand: ""
......//Attention, you should make this class corresponding to your server class IInfo
};
PageMethods.GetServiceInformation(myInfo);
}
window.onload = setTimeout("GetInfo()", 3000);
Referred to #anotherdie. And tell you how to transfer "X"
In your .js
function GetInfo() {
var parameter = {};
parameter.name = "test";
parameter.id = 123;
parameter.state = true;
PageMethods.GetServiceInformation(parameter,
function (res) {
if (res == true) {
//do some
alert("ok");
} else {
//do some
alert("bad");
}
}, function(err){
alert("ERROR: "+err._message);
});
}
in your apsx.cs (you can return a string, a list, a bool, an int or a json object //for json use json.net http://james.newtonking.com/json) for this i'll return a bool.
using System.Web.Services;
[WebMethod]
public static bool GetServiceInformation(ClassData parameters)
{
try
{
//do some
return true;
}
catch(Exception ex)
{
return false;
}
}
in a interface ClassData .cs
public string name { get; set; }
public int id { get; set; }
public bool state { get; set; }
public ClassData(){}
public ClassData(string _name, int _id, bool _state)
{
this.name = _name;
this.id= _id;
this.state = _state;
}
I do the following :
Create New Page and called it : Counts.aspx
protected void Page_Load(object sender, EventArgs e)
{
emp_num = int.Parse(Session["empnum"].ToString());
Thread.Sleep(3000);
string res = GetCounts(emp_num);
Response.Write(res);
}
/***********************************************************************************************/
protected string GetCounts(int empNum)
{
string outbox = UserTransaction.getoutboxCount(empNum, 0);
string inbox = UserTransaction.getinboxCount(empNum, 0);
string archive = UserTransaction.getarchivecount(empNum, 0);
string draft = UserTransaction.getdraftcount(empNum, 0);
return outbox + "~" + inbox + "~" + archive + "~" + draft + "~";
}
and in my main page :
<script type="text/javascript">
function loadXMLDoc() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var split = xmlhttp.responseText.split('~');
var outbox = split[0];
var inbox = split[1];
var archive = split[2];
var draft = split[3];
document.getElementById("lbl_DraftCount").innerHTML = draft;
document.getElementById("lbl_InboxCount").innerHTML = inbox;
document.getElementById("lbl_ApprovedCount").innerHTML = outbox;
document.getElementById("lbl_archive").innerHTML = archive;
}
}
xmlhttp.open("GET", "Counts.aspx", true);
xmlhttp.send();
}
loadXMLDoc();
</script>

How can I map the names of an array of objects to change the field names?

I am sending data from my client to a method on my WebApi controller that accepts a class of ResponseFromClient. As it's WebApi this handles all the conversion from JSON and changes any field names to match the case convention differences between javascript and C#:
public class ResponseFromClient
{
public int QuestionId { get; set; }
public ICollection<AnswerDetail> Answers { get; set; }
public string Task { get; set; }
}
public class AnswerDetail
{
public int AnswerId { get; set; }
public string Text { get; set; }
public bool? Correct { get; set; }
public bool? Response { get; set; }
}
In Javascript I have an array called ans with each element looking like this:
qs.ans[index].id = element.answerId;
qs.ans[index].c = null;
qs.ans[index].r = false;
qs.ans[index].text = element.text;
I need to send the contents of a Javascript object responseFromClient to the C# server program:
var responseFromClient = {
questionId: qs.q,
answers: qs.ans,
task: task
};
$http({
method: 'POST',
url: url,
data: responseFromClient
})
Is there a simple way that I can set the answers field in the javascript variable responseFromClient so that it receives an array that contains objects that map to the AnswerDetail class. In other words I need to change it so that the answers gets and array of objects that are like this:
old > new
id > AnswerID
c > Correct
t > Text
r > Response
I was thinking to do it like I do where I remap qs.q > questionId. However ans is an array so I am not sure how to do this.
Is it not easier allround to map the object onto the class in your JavaScript
qs.ans[index].answerId = element.answerId;
qs.ans[index].correct = null;
qs.ans[index].response = false;
qs.ans[index].text
or
in the ajax call
data: { "answerId" : responseFromClient.id,
"correct": responseFromClient.c,
"response": responseFromClient.t,
"text": responseFromClient.text }
You can simply remap the values you want with arrays of old => new keys. There are more advanced ways of doing this, but I don't know all the details of your case...
function remap(obj, old_keys, new_keys){
var len = old_keys.length;
var new_obj = {};
for (var i = 0; i < len; i++) {
new_obj[new_keys[i]] = obj[old_keys[i]];
}
return new_obj;
}
var len = ans.length;
var old_keys = ["id", "c", "r", "text"];
var new_keys = ["AnswerId", "Correct", "Response", "Text"]
for (var i = 0; i < len; i++) {
ans[i] = remap(ans[i], old_keys, new_keys);
}

Categories

Resources