Reputation: 831
I am attempting to pass a JSON object that contains both generic string properties and an array of objects with properties.
The Model Object:
public class Stock
{
public IEnumerable<Daily> DailyList;
public string Symbol { get; set; }
public double PERatio { get; set; }
}
public class Daily
{
public double EndOfDayPrice { get; set; }
public int Volume { get; set; }
public double DayDiff { get; set; }
}
The following is my HomeController code:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public JsonResult Dump()
{
Stock s = new Stock()
{
Symbol = "YHOO",
PERatio = 4.31,
DailyList = new List<Daily>()
{
new Daily {EndOfDayPrice = 4.13, DayDiff = 1.2, Volume = 15000 },
new Daily {EndOfDayPrice = 4.1, DayDiff = .5, Volume = 1300 }
}
};
return Json(s, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult ProcessDataReturned(Stock stock)
{
stock = stock;
// int count = mylist.Length;
return Json("success");
}
}
This is my JavaScript on my page:
function calculate(pricelist) {
var count = 1; //skip first;
var teststring = { "DailyList": [{ "EndOfDayPrice": 4.13, "Volume": 15000, "DayDiff": 1.2 }, { "EndOfDayPrice": 4.1, "Volume": 1300, "DayDiff": 0.5 }], "Symbol": "YHOO", "PERatio": 4.31 };
$.post("/home/ProcessDataReturned/", teststring).done(function (data2) { document.write(data2 + "<hr>"); });
//Tried with the JSON.stringify also.
$.post("/home/ProcessDataReturned/", JSON.stringify(teststring)).done(function (data2) { document.write(data2 + "<hr>"); });
}
When I go to the controller and watch the value coming over the array of DailyList is always null. The other properties are fine. I have tried to make the Model(C#) to use both IList and IEnumerable for the property.
NEW CODE as suggested by contributors. I am still having the same problem. Array is still empty (not null because I initialize it in the constructor).
var x = JSON.stringify({ stock: teststring });
//Other variations I have tried
//var x = JSON.stringify(teststring);
$.ajax({
url: '@Url.Action("ProcessDataReturned", "home")',
data: x,
type: 'POST',
traditional:true,
contentType: "application/json; charset=utf-8",
success: function (data) {
$('#message').html("Reason was updated");}
});
Solution: Because there were actually multiple pieces wrong I gave credit to each person. Additionally I found one bug on my own. 1. I must use the long form version of the ajax call. ie use $.ajax instead of $.post 2. My model on the server was not set up correctly. I needed to add the "{get;set;}" to the property declaration for the list. Silly mistake on my part and the code below enabled me to see that issue. public class Stock { //public IEnumerable DailyList; //Change this to this (Stupid Mistake): public IEnumerable DailyList {get;set;}; public string Symbol { get; set; } public double PERatio { get; set; } }
Upvotes: 0
Views: 1573
Reputation:
Because your collection items are not correctly names with indexers, your need to use ajax()
with traditional: true
.
var teststring = { "DailyList": [{ "EndOfDayPrice": 4.13, "Volume": 15000, ....}
$.ajax({
type: 'POST',
url: '@Url.Action("ProcessDataReturned", "home")', // do not hard code your urls
traditional: true,
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ stock: teststring }),
....
})
Note if your javascript object was
{ DailyList[0].EndOfDayPrice: 4.13, DailyList[0].Volume: 15000, ..., DailyList[1].EndOfDayPrice: 4.1, DailyList[1].Volume: 1300, ...}
Then the object would be bound using the $.post()
method in your code
Edit
Your Stock
class does not have a property for DailyList
(its a field) and as a result the default model binder cannot set the values. Change it to a property
public IEnumerable<Daily> DailyList { get; set; }
Upvotes: 1