Edit: I’ve got the solution and have described it a bit more at the end of the post
Using: MVC 3, C#
Problem: A key/value obj array sent to controller via $.post/$.ajax results in a 500 internal server error at the controller (because the value passed to the method in the C# controller is null)
I have an array that’s in the format:
{
"q_1": {
"qid": "1",
"tmr": 0
},
"q_2": {
"qid": "2",
"tmr": 0
}
}
I get this via $(“#myid”).data() – and this is all fine.
I need to send this to my controller, and tried both post and $.ajax
var d = $("#q_data").data();
$.post("/run/submit", d, function(data) { alert(data);}, "application/json");
and
$.ajax({
url: '/run/submit',
data: d,
contentType: 'application/json',
dataType: 'json',
success: function (data) { alert(data); }
});
The method on the C# side is
public ActionResult Submit(List<PerfObj> dict)
{
int x = dict.Count;
return PartialView("_DummyPartial");
}
Where PerfObj is my model
public class PerfObj
{
public string id { get; set; }
Perfvar perfVar;
}
public class PerfVar
{
public string qid { get; set; }
/* note I've tried both int and string for the tmr param */
public string tmr { get; set; }
}
When I execute this, the call goes to the controller correctly – i.e. it hits the submit method. However, the method parameter dict, in
List<PerfObj> dict
is null.
Why? It seems to be something with my model, can’t figure out how else to design it so it extracts the values correctly to the method parameter.
When I print the JSON.Stringify on the console, it shows the key/value pair correctly so I’m thinking it’s going correctly to the server but the server/MVC3 doesn’t like it for some reason or can’t map it to the List of PerfObjs.
EDIT: Solution
Maciej’s answer to my post was how I solved it. What I did eventually was to create a arrays of perfObj at the client side
$("#q_data").data(e,{key: e, perfVar: { qid: e, tmr: 0 }})
(ps – ignore redundant usage of ‘e’, I’ve got other plans, this is a dummy case)
And then I mapped it to a JSON friendly array
var arr = [];
$.each($('#q_data').data(), function (i, e) {
var p = $(this).data(i);
var obj = { key: i, perfVar: { id: e.perfVar.qid, tmr: e.perfVar.tmr}};
arr.push(obj);
});
Then stringified it
var q = JSON.stringify(arr);
$.ajax’d it as described in Maciej’s post.
I redefined my classes properly
public class PerfObj
{
public string key { get; set; }
public PerfVar perfVar { get; set; }
}
public class PerfVar
{
public string id { get; set; }
public int tmr { get; set; }
}
and changed the signature of my controller method
[HttpPost]
public ActionResult Submit(PerfObj[] dict)
{
return PartialView("_DummyPartial");
}
This now works perfectly and I can extend my classes fairly easily to do what I want.
Thank you all!
There are 3 things wrong with your code:
A. The property PerfVar must be made public and there must be a get and set on it:
B. Your JSON representation of the list is incorrect. It should be:
C. You have to stringify the array and specify type: ‘POST’ to pass it to your MVC controller via ajax: