JSON, MVC2 Disordered data in even cell cointainers - json

I got into troubles trying to feed the jqgrid with required information. I did everything as suppose to be done, but apparently there is an issue.
Every second cell is order differently, so first row is ok:
[{"id":"AA1","cell":["AA1","AD + DNS + WINS","dev"]},
but the next one is ordered like below:
{"id":"AA2","cell":["dev","AD + DNS + WINS","AA2"]}
when 3rd is ok, and 4th is disordered and so on.
Code which is responsible for this process is below:
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from l in lst
select new
{
id = l.HostName,
cell = new List<string> {
l.HostName, l.Description, l.Type
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
Why is like that? I was trying use instead of List the String[], but Linq doesn't like that and pop up error, which suggest List instead of string array.
Is there any way to sustain desired order?

What was your code to use string[]? I got this working without any trouble:
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (from l in lst
select new
{
id = l.HostName,
cell = new string[] {
l.HostName,
l.Description,
l.Type
}
}).ToArray()
};
You can find similar samples here (but remember that in general they are very old and I would suggest looking at more up to date ones here or here).

Related

Unable to add new key value into an existing JSON Array with JSON objects

Here is what I have tried.
I have tried dot notation and quotes. None of them seem to work. What exactly could be the problem?
var clientsList;
Client.find({}, function(err, clients) {
clientsList = clients;
// I have 10 clients in the loop
for (var j = 0; j < clientsList.length; j++) {
var x = clientsList[j];
x.count = "20";
//x["count"] = "20";
console.log(x);
}
});
Existing Client object
{"name":"abcd", "email":"abc#gmail.com"}
I'm unable to add the count key value pair into the client object. What could be the problem?
I suspect the object you're being given by Client.find has extensions prevented (it's sealed or frozen).
You can create a new object with the original's own, enumerable properties plus your count property using ES2018 spread notation:
x = {...x, count: "20"};
...or ES2015's Object.assign:
x = Object.assign({}, x, {count: "20"});
If the array is also sealed or frozen, you can copy it and its objects like this:
clientList = clients.map(client => {
return {...client, count: "20"}; // Or with `Object.assign`
});
or even with the concise form of the arrow function:
clientList = clients.map(client => ({...client, count: "20"}));
Side note: This pattern:
var clientsList;
Client.find({}, function(err, clients) {
clientsList = clients;
// ...
});
...often suggests that you intend to use clientsList in code following the Client.find call and expect it to have the result from that call's callback. See this question's answers for why, if you're doing that, it doesn't work.

ASP.NET C# Multiple Value Json Serialize

I try to return user informations json value at my web page' load method. My code looks like this.
DataSet dsX = ReadSql("select top 14 * from fuyeler where inStatus = 1 and inUye = 1");
if (dsX.Tables.Count > 0)
{
OYUNCU oyuncular = new OYUNCU();
for (int i = 0; i < dsX.Tables[0].Rows.Count; i++)
{
oyuncular.oyuncuID = Convert.ToInt32(dsX.Tables[0].Rows[i]["inID"]);
oyuncular.oyuncuMail = dsX.Tables[0].Rows[i]["stMail"].ToString();
oyuncular.oyuncuPass = dsX.Tables[0].Rows[i]["stPass"].ToString();
oyuncular.oyuncuToken = dsX.Tables[0].Rows[i]["stToken"].ToString();
}
string json = JsonConvert.SerializeObject(oyuncular);
Response.Clear();
Response.ContentType = "application/json; charset=utf-8";
Response.Write(json);
Response.End();
}`
At the end it returns only 1 value of course. I have tried Arrays and lists but JsonConvert.SerializeObject(array or list) doesnt return as json value. It returns every values on 1 row. I want 1 row for 1 value. What should i do about it?
For this code below Json result looks like this,
{"oyuncuMail":"x#gmail.com","oyuncuPass":"x2008","oyuncuToken":"290620153513","oyuncuID":14}
This output is correct and should dispaly last record of the selected rows from your sql query because in your for loop you don't create new object, you assign values to the same object so it will take the values of the last row
you should do this if you want to get a list :
List<OYUNCU> listOyuncular = new List<OYUNCU>();
for (int i = 0; i < dsX.Tables[0].Rows.Count; i++)
{
var oyunclar = new OYUNCU();
oyuncular.oyuncuID = Convert.ToInt32(dsX.Tables[0].Rows[i]["inID"]);
oyuncular.oyuncuMail = dsX.Tables[0].Rows[i]["stMail"].ToString();
oyuncular.oyuncuPass = dsX.Tables[0].Rows[i]["stPass"].ToString();
oyuncular.oyuncuToken = dsX.Tables[0].Rows[i]["stToken"].ToString();
listOyuncular.Add(oyunclar);
}
string json = JsonConvert.SerializeObject(listOyuncular);

In MVC, pass complex query and view model to session?

I have a view model:
public class UserCollectionView
{
public CardCollection CardCollections { get; set; }
public Card Cards { get; set; }
}
I have a List View Controller:
public ActionResult ViewCollection(int? page)
{
var userid = (int)WebSecurity.CurrentUserId;
var pageNumber = page ?? 1;
int pageSize = 5;
ViewBag.OnePageOfCards = pageNumber;
if (Session["CardCollection"] != null)
{
var paging = Session["CardCollection"].ToString.();
return View(paging.ToPagedList(pageNumber, pageSize));
}
var viewModel = from c in db.Cards
join j in db.CardCollections on c.CardID equals j.CardID
where (j.NumberofCopies > 0) && (j.UserID == userid)
orderby c.Title
select new UserCollectionView { Cards = c, CardCollections = j };
Session["CardCollection"] = viewModel;
return View(viewModel.ToPagedList(pageNumber, pageSize));
I am trying to use the PagedList to add paging to the results. I have been able to do this when I am not using a query that returns data from 2 databases in a single view. As shown here
My end result looks something like this:
Cards.SeveralColumns CardCollections.ColumnA CardCollections.ColumnB
Row 1 Data from Cards Table A from CardCollections B from CardCollections
Row 2 Data from Cards Table A from CardCollections B from CardCollections
Row 3 Data from Cards Table A from CardCollections B from CardCollections
And so on... I get an error
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I have tried variations of SQL statements but can't get it to fit with my view model. In SQL Management Studio this brings back the correct results
Select * from Cards Inner Join CardCollections On Cards.CardID = CardCollections.CardID where CardCollections.UserID = 1 and CardCollections.NumberofCopies > 0;
I need a way to pass the query in session so the paging will operate correctly. Any advice is appreciated. :)
Short answer is, you can't. The model needs to be a snapshot of the content and therefore you can't pass an open query across the boundary (either as a hand-off to a session or to the client directly).
What you're seeing is the disposal of the context beyond it's initial use (where you assemble var viewmodel).
With that said, you can cache the results (to save overhead) if querying the data is an expensive operation. Basically, you'd store the entire collection (or at least a large subset of the collection) in the session/memorycache (which can then be manipulated into a paged list). Something to the effect of:
public ActionResult ViewCollection(int? page)
{
var userId = (int) WebSecurity.CurrentUserId;
var pageNumber = page ?? 1;
var pageSize = 5;
ViewBag.OnePageOfCards = pageNumber;
var cacheKey = String.Format("ViewCollection[{0}]", userId);
var entities = GetOrCreateCacheItem<IEnumerable<UserCollectionView>>(cacheKey, () => {
var query = (from c in db.Cards
join j in db.CardCollections on c.CardID equals j.CardID
where (j.NumberofCopies > 0) && (j.UserID == userid)
orderby c.Title
select new UserCollectionView { Cards = c, CardCollections = j }
)
.ToList(); // Force fetch from Db so we can cache
});
return View(entities.ToPagedList(pageNumber, pageSize));
}
// To give an example of a cache provider; Feel free to change this,
// abstract it out, etc.
private T GetOrCreateCacheItem<T>(string cacheKey, Func<T> getItem)
{
T cacheItem = MemoryCache.Default.Get(cacheKey) as T;
if (cacheItem == null)
{
cacheItem = getItem();
var cacheExpiry = DateTime.Now.AddMinutes(5);
MemoryCache.Default.Add(cacheKey, cacheItem, cacheExpiry);
}
return cacheItem;
}
It turns out that I didn't need to pass the query at all. If I let it run through it works fine without the session. I am not really sure why this works but my search query has to be passed. Maybe it is because I am using a viewmodel to perform the query. I will experiment and post if I find anything. Currently the working code is:
public ActionResult ViewCollection(int? page)
{
var userid = (int)WebSecurity.CurrentUserId;
var pageNumber = page ?? 1;
int pageSize = 5;
ViewBag.OnePageOfCards = pageNumber;
ViewBag.Rarity_ID = new SelectList(db.Rarities, "RarityID", "Title");
ViewBag.MainType_ID = new SelectList(db.MainTypes, "MainTypeID", "Title");
ViewBag.CardSet_ID = new SelectList(db.CardSets, "CardSetID", "Title");
ViewBag.SubType_ID = new SelectList(db.SubTypes, "SubTypeID", "Title");
var viewModel = from c in db.Cards
join j in db.CardCollections on c.CardID equals j.CardID
where (j.NumberofCopies > 0) && (j.UserID == userid)
orderby c.Title
select new UserCollectionView { Cards = c, CardCollections = j };
return View(viewModel.ToPagedList(pageNumber, pageSize));

Facebook C# SDKv6 How to Parse results of Multi Query FQL

I can successfully execute a multi query fql using the facebook c# sdk v 6.14 thanks to Prabir's blog, but need help in parsing the results. I've searched and tried many ways to no avail. I know it is a simple syntax issue, but I'm fairly new to c# and JSON.
Any help is much appreciated!
Thanks,
Chad
My Code:
var fb = new FacebookClient(this.FacebookAccessToken);
dynamic resultsMQFQL = fb.Get("fql",
new
{
q = new
{
friendsMovies = "SELECT page_id, uid FROM page_fan WHERE type='MOVIE' AND uid IN (SELECT uid2 FROM friend WHERE uid1=me()) ORDER BY page_id",
movieDetails = "SELECT page_id, name, pic, fan_count, categories, genre, starring, release_date FROM page WHERE page_id IN (SELECT page_id FROM #friendsMovies) ORDER BY fan_count DESC",
}
});
Results:
{"data":[
{"name":"friendsMovies",
"fql_result_set":
[{"page_id":105638652803531,"uid":796419451},
{"page_id":113271808686307,"uid":796419451}]},
{"name":"movieDetails",
"fql_result_set":[
{"page_id":105638652803531,"name":"Fear and Loathing in Las Vegas"},
{"page_id":113271808686307,"name":"Fletch"}
]
}
]}
Attempt at parsing:
foreach (dynamic row in resultsMQFQL.data.fql_result_set)
Error:
'Facebook.JsonArray' does not contain a definition for 'fql_result_set'
Ok, figured it out...forgot I could try various combinations quickly while debugging in the immediate window...did I say I am fairly new at coding? :)
public void FBMQFQL()
{
var fb = new FacebookClient(this.FacebookAccessToken);
dynamic resultsMQFQL = fb.Get("fql",
new
{
q = new
{
friendsMovies = "SELECT page_id, uid FROM page_fan WHERE type='MOVIE' AND uid IN (SELECT uid2 FROM friend WHERE uid1=me()) ORDER BY page_id",
movieDetails = "SELECT page_id, name, pic, fan_count, categories, genre, starring, release_date FROM page WHERE page_id IN (SELECT page_id FROM #friendsMovies) ORDER BY fan_count DESC",
}
});
//To access a direct value: resultsMQFQL.data[0].fql_result_set[0].page_id
var friendsMovies = resultsMQFQL.data[0].fql_result_set;
var movieDetails = resultsMQFQL.data[1].fql_result_set;
if (resultsMQFQL == null)
{
//return null;
}
else
{
//Construct the new, formated, merged datatable to store the results the way we want them
DataTable dtMyFriendsMovies = new DataTable();
dtMyFriendsMovies.Columns.Add("MovieID");
dtMyFriendsMovies.Columns.Add("FriendUserID");
foreach (dynamic row in friendsMovies)
{
//Add New DataRow to new DataTable
DataRow drRow = dtMyFriendsMovies.NewRow();
//Get various values from original JSON Friend List returned
drRow["MovieID"] = row.page_id;
drRow["FriendUserID"] = row.uid;
//Add New Row to New Resulting Data Table
dtMyFriendsMovies.Rows.Add(drRow);
}
//MovieDetails
DataTable dtMovies = new DataTable();
dtMovies.Columns.Add("movieID");
dtMovies.Columns.Add("name");
dtMovies.Columns.Add("pic");
dtMovies.Columns.Add("fan_count");
dtMovies.Columns.Add("genre");
dtMovies.Columns.Add("starring");
dtMovies.Columns.Add("release_date");
foreach (dynamic row in movieDetails)
{
//Add New DataRow to new DataTable
DataRow drRow = dtMovies.NewRow();
//Get various values from original JSON Friend List returned
drRow["movieID"] = row.page_id;
drRow["name"] = row.name;
drRow["pic"] = row.pic;
drRow["fan_count"] = row.fan_count;
drRow["genre"] = row.genre;
drRow["starring"] = row.starring;
drRow["release_date"] = row.release_date;
//Add New Row to New Resulting Data Table
dtMovies.Rows.Add(drRow);
}
//return dtMyFriendsMovies;
}
} //FB FQL

Error msg on linq to dictionary-"an item of the same key value has already been added"

I'm trying do make a collection using linq based on ID which is a GUID.On using dictionary I'm getting error "An item with same key has already been added" Any suggestion?
foreach (Guid i in ar)
{
var prod = (from r in datacontext.item_tables's where r.itemID == i select r);
Dictionary<Guid, item_tables> tempdata =prod.ToDictionary(s => s.itemID);
Facet[] ftemp = new Facet[tempdata.Count];
string s1 = "";
ftemp[0] = new Facet("descriptiob", FacetType.Text, tempdata[i].Description);
ftemp[1] = new Facet("date", FacetType.Text, tempdata[i].uploaddate);
for (int iv = 0; iv < tempdata.Count; iv++)
{
s1 += tempdata[i].ProductName + " \n";
}
ftemp[2] = new Facet("ProductName", FacetType.Text, s1);
}
You're basically building your dictionary using this code:
datacontext
.item_tables
.Where(r => r.itemID == i)
.ToDictionary(s => s.itemID);
The Where is filtering the results to where itemID is a particular i (Guid) at a time, but can return zero, one, or more, results. Clearly the error you are getting says that for at least one value of i you are getting more than one record returned.
This means the issue either that your database isn't properly normalized or that you've got a logic error in your code.
It sounds like the latter to me.
Further down in your code you have this loop:
for (int iv = 0; iv < tempdata.Count; iv++)
{
s1 += tempdata[i].ProductName + " \n";
}
This says to me that you're expecting the tempdata dictionary to have more than one value - but you're building the dictionary using itemID as the key and this should only put one value in the dictionary based on your query. So something is wrong here in your logic.
Can you describe in more detail what you're trying to do?
Based on your comment below (without the clarification from my comment) this appears to be what you want:
var query =
from r in datacontext.item_tables
group r.ProductName by new
{
r.itemID,
r.Description,
r.uploaddate,
r.ItemName,
};
foreach (var items in query.ToArray())
{
var f0 = new Facet("descriptiob", FacetType.Text, items.Key.Description);
var f1 = new Facet("date", FacetType.Text, items.Key.uploaddate);
var f2 = new Facet("ProductName", FacetType.Text, String.Join("\n", items));
collection.AddItem(items.Key.ItemName, null, null, f0, f1, f2);
}