jquery submit model containing multiple objects - c#

--I've deleted the original text to try to clean the post up a bit--
--------EDIT-------------------------------------------------------------------------
Here is some more info not sure if it helps anyone that's ran into this issue before.
Here is what my final object looks like in the JS script:
var DealerModel = {
Dealer: {
AccountId: 5678,
Name: "Austin",
City: "Who knows",
State: "TN"
},
Test: 111,
DealerCategories: [{Name: "Test1", Value:"Value1"},{Name:"Test2", Value:"Value2"}]
}
When I pass this into my controller via jquery it has the 111 value for Test, it shows that DealerCategories has 2 objects, but for both those objects as well as Dealer it shows NULL.
I've changed up the model/controller a few times and it seems no matter what if I pass in an object that has a sub json object it doesn't like that. I have a feeling this is something simple i'm missing.

the model binder knows how to bind arrays from JSON so you just have to give him something like this :
var DealerModel =
{
Dealer : 'my_dealer_value_here',
DealerContact = [] <- a list of Contrats here
}
and i think this should do it.

If your issue is with taking the leap from posting simple values like strings and numbers through jQuery.post, you can also provide json objects, like the one listed by Alex, above.
$.ajax({
type: "POST",
url: 'MYURL',
data: {
Dealer : {id:-1, accountId: '', name:'TheDealer'},
DealerContact: [{FirstName:'ContactName',...},{...},...]
}
});
And that bit of data should deserialize to your objects.

Related

ajax object sending to controller not working

I just wanted to send list of Id numbers which collected from checkbox values. Following example code i already tried but not working mvc controller doesn't grab any Id values. Please check code bellow and tell me whats wrong i am doing here.
var _groupids = [];
$('input[class="groupids"]:checked').each(function() {
_groupids.push(this.value);
});
var ticks = {};
$.each(_groupids, function(key, value) {
ticks['Id'] = value;
});
console.log(ticks);
$.post('/MyController/Create', {
groupIds: JSON.stringify(ticks)
}).done(function(data) {
});
Model:
namespace Demo.ViewModels
{
public class Ppp
{
public int Id { get; set; }
}
}
Controller:
[HttpPost]
public ActionResult Create(List<Ppp> data)
{
//want to get ajax value in `data`
}
Note: I also tried removing JSON.stringify but still not receives any value in controller
I also tried to sending this value like this ticks = '[{"Id": 1}, {"Id": 2}, {"Id": 3}]'; and still not receives any value in controller
Many issues here:
ticks['Id'] = value uses the same key at each iteration. You are effectively overriding the value from the previous iteration.
However that wouldn't help, because you need to post a list, and you are posting an object that looks something like this: {"Id": 4}. That's not a list by any measure.
You call parameter groupIds in js, while controller expects data.
So you need to make sure your parameter names match, and the data that you send should be looking like that:
[{"Id": 1}, {"Id": 2}, {"Id": 3}]
You can do that if ticks was an array, and got inserted a new object on each iteration.

How to use IEnumerable<ExpandoObject> in knockout.js?

Problem Description
I wanted to ask about how to use a list Exbando Objects in knockout.js,am using Rob Conrey's Massive and all returned results are dynamic, that's fine with me it suits my needs but when it comes to sending results to knockout i just don't know what to do with it.
Goal
Access object properties like obj.Name, obj.Brand etc...
Sample Code
View:
<div data-bind="foreach: Products">
<p>Product name: <strong data-bind="text: Name"></strong></p>
</div>
Controller:
public JsonResult GetProducts()
{
Products products = new Products();
var Model = products.GetAllProducts();
return Json(Model, JsonRequestBehavior.AllowGet);
}
The result of calling GetProducts is:
[[{"Key":"Id","Value":1},{"Key":"Name","Value":"Badass Boots"},{"Key":"Brand","Value":"Nike"},{"Key":"Description","Value":"Super cool boots that can make you fly (Not Really!)."}, etc...]]
Script File:
function ProductListViewModel() {
// Data
var self = this;
self.Products = ko.observableArray([]);
$.getJSON("/Home/GetProducts", function (data) {
self.Products(data);
});
}
JavaScript error on running the application:
Uncaught ReferenceError: Unable to parse bindings. Bindings value: text: Name Message: Name is not defined
Screen Shot 1:
Screen Shot 2:
An ExpandoObject generally speaking is for all intents and purposes, a dictionary. When serialized as JSON here, it is treated as a dictionary and becomes a collection of key/value pairs (not all serializers behave this way, but the one you're using does). It is not an object you can access members by name, you'll have to convert it into a representation where you can (or serialize it as one in the first place).
Doing the conversion is not the worst thing in the world:
function Product(item) {
var self = this;
// assuming item is an array of key/value pairs
ko.utils.arrayForEach(item, function(pair) {
// doesn't necessarily have to be mapped as an observable
self[pair.Key] = ko.observable(pair.Value);
});
}
With this, you can then map the results to your array of products:
$.getJSON("/Home/GetProducts", function (data) {
self.Products(ko.utils.arrayMap(data, function(item) {
return new Product(item);
}));
});
It looks like the problem is because you are trying to set the value of your ko.observableArray to a json array. Not sure that this will work. Typically this is how I would do it:
function ProductListViewModel() {
// Data
var self = this;
self.Products = ko.observableArray([]);
$.getJSON("/Home/GetProducts", function (data) {
ko.utils.arrayForEach(data, function(item) {
self.Products.push({
Name : item.Name
});
});
});
}
Use knockout's arrayForEach function to iterate through your json array, and push each object into your observableArray.
As in your JSON I see the sequence of Key and Value, so you have to specify the filed name which knockout has to query for to get the relative value and put it on the screen.
So change <strong data-bind="text: Name"> to <strong data-bind="text: Key"> and this should work for you.

reading JSON data from aspx web form

I have an Regular ASP.Net web form (not a web service) that I'm trying to spit out JSON data which I'm then trying to consume. I have a 2 part question.
The 1st one is dealing with outputting the JSON data:
var reader2 = command.ExecuteReader();
while (reader2.Read())
{
var json = Json.Encode(new{
code = reader2[1].ToString(),
Revenue = reader2[4].ToString()
});
Response.Write(json);
}
reader2 contains 238 different entries. Right now the above Response.Write(json) returns 238 separate json strings:
{"code":"123","Revenue":"90.0000"}{"code":"234","Revenue":"90.0000"}
I think it might be helpful later (for question 2) if I had them grouped into 1 recordset.
{ "records": [ { "code":"123" , "Revenue":"90.0000" }, {
"code":"234" , "Revenue":"90.0000" } ] }
How would I do that with the above snippet using the reader and the System.Web.Helpers.Json?
The second question might be a direct result of how I'm currently outputting the JSON data from the first question. Ultimately I want to be able to read what ever I output from question 1 using this function. Right now my I set my dataType: "html" as that is the only thing I could get to return anything. However, that gives me a length for my msg of 32000+... Something isn't right.
What do I have to do to be able to read the JSON data output from my ASPX page?
function populateResults(code, district, year) {
$.ajax({
type: "GET",
url: "regular.aspx",
data: "code=" + code + "year=" + year,
dataType: "html",
success: function (msg) {
var results = msg;
$.each(results, function (index, result) {
console.log(result.code);
});
}
});
Re-reading the question after my comment, it's a little more clear now that "32000" isn't too much data in general, it's just that the data is being treated as one big string instead of as an array of objects.
This is probably because the data type is HTML, which is probably necessary because it's not seeing the response as correctly formatted JSON. I think you're right that it needs to be "grouped" though it might not need to be wrapped in a parent object like that. Try prepending with a [, appending with a ], and separating each with a comma. Maybe something like this:
var reader2 = command.ExecuteReader();
Response.Write("[");
var firstRecord = true;
while (reader2.Read())
{
if (!firstRecord)
Response.Write(",");
firstRecord = false;
var json = Json.Encode(new{
code = reader2[1].ToString(),
Revenue = reader2[4].ToString()
});
Response.Write(json);
}
Response.Write("]");
I had to throw in a little logic there to determine when to include a comma, since you don't want one before the first record or after the last record. There may be a more elegant way to do that, especially if you know the count coming from reader2. But hopefully you get the idea.
This should result in something more like this:
[{"code":"123","Revenue":"90.0000"},{"code":"234","Revenue":"90.0000"}]
Which by itself should be interpretable as JSON by the browser. This should allow you to set the data type:
dataType: "json"
Which should, in turn, give you what you're looking for in msg.
Edit: You may be able to simplify this a little more by turning the output from reader2 into an enumeration of objects and just using Json.Encode() on that whole thing. Maybe something like:
var records = new List<CustomRecord>();
while (reader2.Read())
{
records.Add(new CustomRecord {
code = reader2[1].ToString(),
Revenue = reader2[4].ToString()
});
}
Response.Write(Json.Encode(records));
And have a simple custom object:
class CustomRecord
{
public string code { get; set; }
public string Revenue { get; set; }
}

Array Passed to Controller Received as NULL

I'm using $.post() to post an array of integer values to my controller.
Here's how I construct my array:
var ratings = [];
$('#ratings input[name=newReviewRatings]').each(function () {
ratings.push($(this).val());
});
Here's how I'm posting it to the controller:
$.post('#Url.Action("CreateReview", "Provider")',
{
id: providerId,
ratings: ratings,
comment: comment
});
Here's the form data that gets posted:
{id=437baf29-4196-4966-88de-a8fde87ef68d&ratings%5b%5d=1&ratings%5b%5d=2&ratings%5b%5d=3&ratings%5b%5d=4&ratings%5b%5d=5&comment=Comments}
And here's my controller signature:
public ActionResult CreateReview(Guid id, int[] ratings, string comment)
{
// ....
}
That seems like that should be right, but ratings is always null. Can anyone see what I'm missing?
I also tried string[] ratings and got the same result. I also saw a suggestion to pass the array using JSON.stringify(ratings) but that didn't seem to help either.
In adition to converting the post data to json, you can also set the traditional param to true. This will cause jQuery to use the correct post format for MVC.
jQuery.ajaxSettings.traditional = true;
$.post('#Url.Action("CreateReview", "Home")',
{
id: 'GUID STRING HERE',
ratings: [1, 2, 3],
comment: 'adfef'
});
Try to specify contentType like this:
$.ajax({
url:url,
type:"POST",
data:data,
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(){
...
}
})

value not passing

I'm trying to send selected checkbox values to another asp page to update database.
$("#Delete_selected_Comment_button").click(function () {
var dataToBeDeleted = new Array();
$('.checkboxes_to_delete:checked').each(function (key, value) {
dataToBeDeleted .push($(this).val());
});
$.ajax({
url: 'http://myurl.aspx',
type: 'GET',
data: dataToBeDeleted,
success: function () { alert('yipee'); },
error: function () { alert("Ooff could not delete data"); }
});
});
Problem:
I am not able to retrieve any value in myurl.asp page.
I am doing:
String datagotfromajax= request.QueryString[dataToBeDeleted];
Am doing this incorrectly? Where is my mistake ? Can anyone help please?
An easy way would be to change one line:
data: "ids="+dataToBeDeleted.join(","),
And, in the server do:
string[] ids = Request.QueryString["ids"].ToString().Split(",");
With this you'll hava a string array in the server with the corresponding checkboxes values.
HOpe this helps.
dataToBeDeleted will be converted to a query string (if its not already) when sent to the server, that means it consists key-value pairs, i.e. foo=bar&fred=fish. On the server you can query individual key-value pairs using the syntax
string bar = request.QueryString["foo"];
You are passing an array as the data parameter. This won't work. You need to pass an object. If the object contains an array, this will be serialized appropriately. This means your code should probably look like this:
data: {
toBeDeleted: dataToBeDeleted
},
This will then be serialized appropriately (see $.param for the serialization process) and you can retrieve the values with your back-end code.

Categories

Resources