Serialize list of dictionaries into accepted DataTable Ajax object - c#

I have a web application in which I'm retrieving some data into bootstrap table, what i want to do now is to use jQuery DataTable instead of the current as it has too much useful features.
Currently I'm retrieving the data from the server side using OOP approach, where a class object represents a data row in a particular table, and this object includes a dictionary which stores column names and values.
What I'm doing now is that I'm retrieving these class objects and append each dictionary of each object in a List<Item> and then serialize this list using JavaScriptSerializer object, and this object returns the following JSON format:
[
{
"slno":"2",
"status_message":"Lights still flashing",
"crm_services_id":"1", "subject_id":"Lights are flashing",
"severity_id":"5",
"user_id":"husain.alhamali",
"status_id":"1"
},
{
"slno":"3",
"status_message":"lights working fine",
"crm_services_id":"2",
"subject_id":"Lights are flashing",
"severity_id":"3",
"user_id":"husain.alhamali",
"status_id":"2"
}
]
When i tried to use this object to fill my DataTable AJAX I've got an error says:
Invalid JSON response
I saw some examples of a valid JSON response that is acceptable to a DataTable which is as follow:
{
"data": [
[
"Tiger Nixon",
"System Architect",
"Edinburgh",
"5421",
"2011/04/25",
"$320,800"
],
[
"Garrett Winters",
"Accountant",
"Tokyo",
"8422",
"2011/07/25",
"$170,750"
]
}
Now my question is is there any tool or plugin that could re-format my JSON string into an acceptable format like the one above?

With this HTML:
<table id="example"></table>
This JS will create a table:
var data = [{
"slno": "2",
"status_message": "Lights still flashing",
"crm_services_id": "1",
"subject_id": "Lights are flashing",
"severity_id": "5",
"user_id": "husain.alhamali",
"status_id": "1"
}, {
"slno": "3",
"status_message": "lights working fine",
"crm_services_id": "2",
"subject_id": "Lights are flashing",
"severity_id": "3",
"user_id": "husain.alhamali",
"status_id": "2"
}];
function getColumns(){
for(var i = 0; i < data.length; i++){
let columnsArray = [];
var keys = Object.keys(data[i]);
for(k in Object.keys(data[i])){
if(data[i].hasOwnProperty(keys[k])){
columnsArray.push({
"data":keys[k]
});
}
}
return columnsArray;
}
}
$(document).ready(function() {
var table = $('#example').DataTable({
"columns": getColumns(),
"data": data
});
});
Working example. Hope that helps.

dataTable require json data in return from ajax response having following keys
1. data
2. draw
3. recordsTotal
4. recordsFiltered

Use this:
var data = list.Select(u => u.GetType()
.GetProperties()
.Select(p => p.GetValue(u, null)));
example
public class User
{
public int userId { get; set; }
public string name { get; set; }
}
public class Programm
{
static void Main()
{
var list = new List<User>();
list.Add(new User
{
userId = 1,
name = "name 1",
});
list.Add(new User
{
userId = 2,
name = "name 2",
});
var data = list.Select(u => u.GetType()
.GetProperties()
.Select(p => p.GetValue(u, null)));
Console.WriteLine(new JavaScriptSerializer().Serialize(new
{
data = data
}));
}
}
result
{
"data" : [
["1", "name 1"],
["2", "name 2"]
]
}

Related

Formatting my json in my C# app in a specific way

I am working on a C# app to work with a 3rd party vendor. They've requested that our JSON be formatted as such (note the "owner" array value)
var good =
{
"id": "0DE570C8-E578-48A9-B22A-F95BC6211B4F",
"make": "Subaru",
"index": "Forester",
"year": "2013",
"owner":
[
{
"First": "Bob",
"Last": "Smith"
}
]
}
In my code, I am unable to get the formatting correct. I am able to produce valid C#, but it doesn't add "owner" as an array and any attempt to make it an array (e.g. adding "[]" after the "new" produces an error ("The name 'x' does not exist in the current context"). Here is my attempted C# code:
var car = new
{
id = "0DE570C8-E578-48A9-B22A-F95BC6211B4F",
make = "Subaru",
model = "Forester",
year = "2013",
Owner = new
{
First = "Bob",
Last = "Smith"
}
};
I tried making a "Car" class and tried using an anonymous type.
Your JSON field for owner is an array and in your code you assign it as an object so you need to assign owner to an array like below:
var car = new
{
id = "0DE570C8-E578-48A9-B22A-F95BC6211B4F",
make = "Subaru",
model = "Forester",
year = "2013",
Owner = new[]
{
new { First = "Bob", Last = "Smith" }
}
};

Filtering query from database

I have a problem because I am new to mongodb and c#. I hope you can help.
I need to add a filter when retrieving data from database. Objects in ProductAttributeCombinations in the database exist more than once. I'm getting data from these objects to the variable named ProductAttributeText, but it comes as a list because there is more than one data in the object. What I need to do is to compare the value under a different object in the database with the values ​​under this object and get the data accordingly.
My codes where I get the data
var querySpec = await _productRepository.Collection
.Aggregate()
.Unwind(x => x.ProductAttributeMappings)
.Project(new BsonDocument {
{ "ProductAttributeId", "$ProductAttributeMappings.ProductAttributeId" },
{ "ProductAttributeValues","$ProductAttributeMappings.ProductAttributeValues.Name" },
{ "ProductAttributeCombination","$ProductAttributeCombinations.Text" },
})
.Unwind("ProductAttributeValues")
.Group(new BsonDocument {
{"_id",
new BsonDocument {
{ "ProductAttributeId", "$ProductAttributeId" },
{ "ProductAttributeName", "$ProductAttributeValues" },
{ "ProductAttributeText", "$ProductAttributeCombination" },
}
},
{"count",
new BsonDocument {
{ "$sum" , 1}
}
}
}).ToListAsync();
If one of the list elements returned to me is like this
{{ "_id" : { "ProductAttributeId" : "60daf1f56b2621a0b7942eac", "ProductAttributeName" : "50", "ProductAttributeText" : ["30", "30", "30", "3", "3", "3", "30", "30", "30"] }, "count" : 3 }}
When I add the filtering like this and add it as Match(filterAttr) to my code, QuerySpec returns null. Am I making a mistake in filtering?
var filterDefAttr = new FilterDefinitionBuilder<BsonDocument>();
var filterAttr = (filterDefAttr.Eq("ProductAttributeCombinations.Attributes.Value", "ProductAttributeMappings.ProductAttributeValues._id"));

MongoDB - How to update a single object in the array of objects inside a document

I have the following document structure:
{
"Agencies": [
{
"name": "tcs",
"id": "1",
"AgencyUser": [
{
"UserName": "ABC",
"Code": "ABC40",
"Link": "http.ios.com",
"TotalDownloads": 0
},
{
"UserName": "xyz",
"Code": "xyz20",
"Link": "http.ios.com",
"TotalDownloads": 0
}
]
}
]
}
Like I have multiple agencies and each agency contains a list of agents.
What I am trying is to pass the Code and update the TotalDownloads field of the agent that matches the code.
For example, if someone uses the code ABC40 so I need to update the field TotalDownloads of the agent called "ABC".
What I have tried is as below:
public virtual async Task UpdateAgentUsersDownloadByCode(string Code)
{
var col = _db.GetCollection<Agencies>(Agencies.DocumentName);
FilterDefinition<Agencies> filter = Builders<Agencies>.Filter.Eq("AgencyUsers.Code", Code);
UpdateDefinition<Agencies> update = Builders<Agencies>.Update.Inc(x => x.AgencyUsers.FirstOrDefault().TotalDownloads, 1);
await col.UpdateOneAsync(filter, update);
}
It is giving me the following error:
Unable to determine the serialization information for x => x.AgencyUsers.FirstOrDefault().TotalDownloads.
Where I'm wrong?
Note: From the attached sample document, the array property name: AgencyUser is not matched with the property name that you specified in the update operation, AgencyUsers.
Use arrayFilters with $[<identifier>] positional filtered operator to update the element(s) in the array.
MongoDB syntax
db.Agencies.update({
"AgencyUsers.Code": "ABC40"
},
{
$inc: {
"AgencyUsers.$[agencyUser].TotalDownloads": 1
}
},
{
arrayFilters: [
{
"agencyUser.Code": "ABC40"
}
]
})
Demo # Mongo Playground
MongoDB .NET Driver syntax
UpdateDefinition<Agencies> update = Builders<Agencies>.Update
.Inc("AgencyUsers.$[agencyUser].TotalDownloads", 1);
UpdateOptions updateOptions = new UpdateOptions
{
ArrayFilters = new[]
{
new BsonDocumentArrayFilterDefinition<Agencies>(
new BsonDocument("agencyUser.Code", Code)
)
}
};
UpdateResult result = await col.UpdateOneAsync(filter, update, updateOptions);
Demo

How to return a List of all values in a field

I have a document like:
{
"Id":"1",
"Name":"product1",
"Categories":["Cat1",
"Cat2",
"Cat3"]
},
{
"Id":"2",
"Name":"product2",
"Categories":["Cat3",
"Cat2",
"Cat6"]
}
Now I want return a distinct List of all categories.
I tried CollapseParameter, but it doesn't work.
var foo = _solr.Query(new SolrQuery("*"), new QueryOptions
{
Collapse = new CollapseParameters("Categories")
});
var bar= results.CollapseExpand; //NULL
How can I get a list of all categories without iterating through all the documents? Do I have to create new Documents for the categories? Or should I work with Faceting?
It looks like the JSON is not valid. So I created a solution changing the Json:
{
"items": [{
"Id": "1",
"Name": "product1",
"Categories": ["Cat1", "Cat2", "Cat3"]
}, {
"Id": "2",
"Name": "product2",
"Categories": ["Cat3", "Cat2", "Cat6"]
}]
}
And then, I used foreach and LINQ structure:
var x = categories.SelectMany(item => item.Categories).Distinct();
If you are using solr and you want all distinct value for specific field then must start reading solr faceting doc, its amazing.
Only add below query in your query and you we get full list of all distinct categories.
&facet=true&facet.field=Categories
That's it, It will gives result set as you expected.
QueryOptions options = new QueryOptions
{
StartOrCursor = new StartOrCursor.Start(0),
Rows = 1,
Facet = new FacetParameters { Queries = new[] { new SolrFacetFieldQuery("Categories") } }
};
var result = _solrConnection.Query(new SolrQuery("*"), options);
if (result.FacetFields.ContainsKey("Categories"))
{
return result.FacetFields["Categories"]
.Where(li => li.Value > 0)
.Select(y=> y.Key)
.ToList();
}
That's my current solution. It works, but I hoped there would be a better way. I'm searching for a result just to get all the categories.

Populate KendoUi Treeview with RavenDB documents

I am using MVC4 and C#.
I have a KendoUI Treeview and I'd like to populate it with data from RavenDB.
In the demo they use this:
public JsonResult Employees(int? id)
{
var dataContext = new NorthwindDataContext();
var employees = from e in dataContext.Employees
where (id.HasValue ? e.ReportsTo == id : e.ReportsTo == null)
select new {
id = e.EmployeeID,
Name = e.FirstName + " " + e.LastName,
hasChildren = e.Employees.Any()
};
return Json(employees, JsonRequestBehavior.AllowGet);
}
Notice the argument "id" - it's an int. In RavenDb document ID's are strings eg. myDco/231...
Imagine this is a standard document:
{
"CreationDate": "12/12/2012 8:07:59 PM",
"Name": "jkljklk",
"Type": "kljkljkljkljkl",
"Description": "ljkljklj",
"CreatedByUser": "ljklklkljklj",
"Deleted": false,
"Status": "NEW",
"Parent": "product/546"
}
How would I populate the treeview?
There should not be any problem to use string instead of that int. You just need to fetch the needed records depending on that string parameter passed to the Action method.
I figured this out.
I changed my RavenDB Document to include a list of all its children:
{
"CreationDate": "12/12/2012 9:33:34 PM",
"Name": "hohoho",
"Type": "hohohoh",
"Description": "hohohoh",
"CreatedByUser": "hohohoh",
"Deleted": false,
"Status": "NEW",
"Parent": "ohohohoh",
"Children": [
"item/1",
"item/2",
"item/3"
]
}
I then returned a list of my items to the View via the controller and then iterated through them, appending all the children to their correct parent nodes:
#(Html.Kendo().TreeView().Name("TreeView").DragAndDrop(true)
.Items(treeview =>
{
foreach (var myItem in Model)
{
var myItemName = myItem.Name;
var children = myItem.Children;
treeview.Add().Text(myItemName ).Expanded(false).Items(branch =>
{
if (children != null)
{
foreach (var child in children)
{
branch.Add().Text(child);
}
}
});
}
}
))
Anyway, thanks for the responses :)
Hope this helps someone else one day.

Categories