jsonResult with collectionname - c#

Hi I would like to use the json collection from the code below in an angular repeater.
I need to give the collection a name but i dont know how
this is the code to generate the JSON
public JsonResult GetProducts()
{
var result = db.Products.ToList();
var list = JsonConvert.SerializeObject(result, Formatting.None, new JsonSerializerSettings(){ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore});
return Json(list,JsonRequestBehavior.AllowGet);
}
and this is the result
[{
"Category": {
"ID": 4,
"Name": "TEST"
},
"OrderDetails": [],
"ID": 10006,
"Description": "TEST",
"Name": "TEST",
"Price": 3.20,
"PictureUrl":"",
"CategoryId": 4,
"AddedToShop": "2016-12-11T14:52:57.677"
},
{
"Category": {
"ID": 4,
"Name": "TEST"
},
"OrderDetails": [],
"ID": 20005,
"Description": "TEST2",
"Name": "TEST2",
"Price": 3.20,
"PictureUrl":"",
"CategoryId": 4,
"AddedToShop": "2016-12-12T12:02:10.593"
}]
and I would like it to be like the code below so I can use the products tag to iterate .
{
"products": [{
"Category": {
"ID": 4,
"Name": "TEST"
},
"OrderDetails": [],
"ID": 10006,
"Description": "TEST",
"Name": "TEST",
"Price": 3.20,
"PictureUrl":"",
"CategoryId": 4,
"AddedToShop": "2016-12-11T14:52:57.677"
},
{
"Category": {
"ID": 4,
"Name": "TEST"
},
"OrderDetails": [],
"ID": 20005,
"Description": "TEST2",
"Name": "TEST2",
"Price": 3.20,
"PictureUrl":"",
"CategoryId": 4,
"AddedToShop": "2016-12-12T12:02:10.593"
}]}

If you are using WebAPI controllers you don't need to send JsonResult, all you need to do is create a class and send it back to client:
public class MyClass
{
public List<Product> Products { get; set; }
}
And in your controller:
public MyClass Get() {
return new MyClass {
Products = db.Products.ToList()
};
}
OR:
Simply create your object and then pass it in the serializer:
JsonConvert.SerializeObject( { "products": result }, Formatting.None, new JsonSerializerSettings(){ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore})

You can use
var list = JsonConvert.SerializeObject(new { products = result }, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore });

One solution for your problem is, define a seperate class and define a property for that class as either a collection or list of the type "db.Products"(Use the appropriate class name for this object as you have in your code) and when you serialize that object you will get it as you have asked for
class ProductList
{
public Collection<YourType> Products{get; set;}
}
OR
class ProductList
{
public List<YourType> Products{get; set;}
}

Related

Newtonsoft Json - Serialize Deep nested object based on given selected properties

Does Newtonsoft Json have any way to serialize nested objects with only selected properties ?
The model looks like:
class Node
{
int id{ get; set; };
string name{ get; set; };
IList<Node>children{ get; set; };
}
I am creating a tree structure afterwards which looks something like this:
{
"id": 1,
"name": "A",
"children": [
{
"id": 2,
"name": "B",
"children": null
},
{
"id": 3,
"name": "C",
"children": [
{
"id": 10,
"name": "D",
"children": null
}
]
}
]
}
Wrote my own serializer. I passed Children property only .It shows as:
{
"children": [
{
"children": null
},
{
"children": [
{
"children": null
}
]
}
]
}
I want to show all properties and not just children under 1st/root's children.Similar to below.
{
"children": [
{
"id": 2,
"name": "B",
"children": null
},
{
"id": 3,
"name": "C",
"children": [
{
"id": 10,
"name": "D",
"children": null
}
]
}
] }
Also how do I do the same for children.Id where I want to serialize all children.Id of root node,Similar to below
{
"children": [
{
"id": 2
},
{
"id": 3
}
]
}
they have done the same result you want to achieve on this page.
https://weblog.west-wind.com/posts/2012/aug/30/using-jsonnet-for-dynamic-json-parsing
Also, see Here,
https://entityframeworkcore.com/knowledge-base/58283745/self-reference-when-serializing-nested-object
I hope that will be useful.
What do you need your own serializer for? Try the standard one
var jsonDeserialized = JsonConvert.DeserializeObject<Child>(json);
json = JsonConvert.SerializeObject(jsonDeserialized);
Output
{
"id": 1,
"name": "A",
"children": [
{
"id": 2,
"name": "B",
"children": null
},
{
"id": 3,
"name": "C",
"children": [
{
"id": 10,
"name": "D",
"children": null
}
]
}
]
}
Classes
public partial class Child
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("children")]
public List<Child> Children { get; set; }
}
For this
{
"children": [
{
"id": 2,
"name": "B",
"children": null
},
{
"id": 3,
"name": "C",
"children": [
{
"id": 10,
"name": "D",
"children": null
}
]
}
] }
You can use
var jsonDeserialized = JsonConvert.DeserializeObject<Data>(json);
public partial class Data
{
[JsonProperty("children")]
public List<Child> Children { get; set; }
}

Filtering Nested array with linq

I have an array like this coming from API response and I want to filter by nested property products to returns product with only id 11
"assets": [
{
"name": "abc",
"products": [
{
"id": "11",
"status": true
},
{
"id": "14",
"status": null
}
]
},
{
"name": "xyz",
"products": [
{
"id": "11",
"status": true
},
{
"id": "28",
"status": null
}
]
},
{
"name": "123",
"products": [
{
"id": "48",
"status": null
}
]
},
{
"name": "456",
"products": [
{
"id": "11",
"status": true
}
]
}
]
the resulting output should look like this,
"assets": [
{
"name": "abc",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "xyz",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "123",
"products": []
},
{
"name": "456",
"products": [
{
"id": "11",
"status": true
}
]
}
]
I'm trying to return filter output with the C# LINQ method. but, getting an error when filtering a nested array with the following method
"Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type"
assets.Select(asset => asset.products.Where(product => product.id == "11")).ToArray();
You can just remove all items from every products array, whose id doesn't equal 11. Parse JSON to JObject, iterate over assets array, find products with id different from 11 and remove them form original array
var json = JObject.Parse(jsonString);
foreach (var asset in json["assets"])
{
var productsArray = asset["products"] as JArray;
if (productsArray == null)
continue;
var productsToRemove = productsArray
.Where(o => o?["id"]?.Value<int>() != 11)
.ToList();
foreach (var product in productsToRemove)
productsArray.Remove(product);
}
Console.WriteLine(json);
Instead of Select and Applying a, Where try to remove the Products that you do not want.
Following is a sample code.
class Program
{
static void Main(string[] args)
{
var json = #"
{
'assets': [
{
'name': 'abc',
'products': [
{
'id': '11',
'status': true
},
{
'id': '14',
'status': null
}
]
},
{
'name': 'xyz',
'products': [
{
'id': '11',
'status': true
},
{
'id': '28',
'status': null
}
]
},
{
'name': '123',
'products': [
{
'id': '48',
'status': null
}
]
},
{
'name': '456',
'products': [
{
'id': '11',
'status': true
}
]
}
]}";
var root = JsonConvert.DeserializeObject<Root>(json);
var assets = root.Assets;
assets.ForEach(a =>
{
a.Products.RemoveAll(p => p.Id != 11);
});
}
}
public partial class Root
{
[JsonProperty("assets")]
public List<Asset> Assets { get; set; }
}
public partial class Asset
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("products")]
public List<Product> Products { get; set; }
}
public partial class Product
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("status")]
public bool? Status { get; set; }
}
To filter the list, you will need to create a new list with products whose ID == YourId. Following linq query does the necessary steps to create the list you want.
Filter out any assets that dont have any product with ID == 11. This is necessary to skip nulls in the new list that will be generated (Where statement)
Create a collection / list of new assets that only have the products whose ID == 11 (Select statement)
var list = assets.Where(x => x.Products.Where(y => y.Id.Equals("11")).Count() > 0)
.Select(asset => {
return new Asset() {
Name = asset.Name,
Products = asset.Products.Where(x => x.Id == "11").ToList()
};
}).ToList();
// Create the RootObject that holds a list of all the arrays if you want.
Rootobject newAssetCollection = new Rootobject() { Assets = list };
Below is the Json that was printed
Console.WriteLine(JsonConvert.SerializeObject(newAssetCollection, Formatting.Indented));
{
"assets": [
{
"name": "abc",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "xyz",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "456",
"products": [
{
"id": "11",
"status": true
}
]
}
]
}

How do I sort a list based on its child object attributes?

I'm wondering if someone can elucidate a method to sort a list of objects based on a child object's attribute.
I'm working with the following model:
public class Content
{
public string Id { get; set; }
public List<ContentAttribute> Attributes { get; set; }
}
public class ContentAttribute
{
public string Value { get; set; }
public string Id { get; set; }
public string Name { get; set; }
}
Some sample data:
[
{
"Id": "123",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name1"
},
{
"Value": "ghi",
"Id": "2b",
"Name": "name2"
}
]
},
{
"Id": "456",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name2"
},
{
"Value": "def",
"Id": "2b",
"Name": "name3"
}
]
},
{
"Id": "789",
"Attributes": [
{
"Value": "abc",
"Id": "1a",
"Name": "name1"
},
{
"Value": "def",
"Id": "2b",
"Name": "name2"
}
]
}
]
How can I sort the Content objects by the Value of a specific attribute Name? For example, I would like to sort the above data by the Value of 'name2',
meaning the result would be
[
{"Id" : "456"},
{"Id" : "789"},
{"Id" : "123"}
]
Any help is greatly appreciated. (Using c#).
If Attributes always has an element with name name2 and you want an exception if it doesn't then:
var sorted = contents.OrderBy(c => c.Attributes.First(a => a.Name == "name2").Value).ToList();
Or if name2 could be missing and it's not deal breaker then use FirstOrDefault
var sorted = contents.OrderBy(c => c.Attributes.FirstOrDefault(a => a.Name == "name2")?.Value).ToList();

How can I display a property value infront of each JSON array item?

Here is the JSON string that I am working with.
{
"id": 1,
"title": "A Test",
"items": [
{
"id": 157,
"title": "some article",
"type": "Article"
},
{
"id": 153,
"title": "some other article",
"type": "Article"
}
]
}
I am using Json.Net for serialization. Is there anyway that I can format the JSON like this before displaying?
{
"id": 1,
"title": "A Test",
"items": [
"157" : {
"title": "some article",
"type": "Article"
},
"153" : {
"title": "some other article",
"type": "Article"
}
]
}
Thanks in advance.
You can get pretty close to the output you want using Json.Net's LINQ-to-JSON API (JObjects) to transform the original JSON. Here is one way to do it:
public static string Transform(string json)
{
JObject root = JObject.Parse(json);
JObject itemsObj = new JObject();
foreach (JObject item in root["items"])
{
JToken id = item["id"];
id.Parent.Remove();
itemsObj.Add(id.ToString(), item);
}
root["items"].Parent.Remove();
root.Add("items", itemsObj);
return root.ToString();
}
If you pass your original JSON to this method, you will get the following output:
{
"id": 1,
"title": "A Test",
"items": {
"157": {
"title": "some article",
"type": "Article"
},
"153": {
"title": "some other article",
"type": "Article"
}
}
}
Fiddle: https://dotnetfiddle.net/1di41P

Build JSON Hierarchy from Structured Data

C# | .NET 4.5 | Entity Framework 5
I have data coming back from a SQL Query in the form of ID,ParentID,Name. I'd like to take that data and parse it into a Hierarchical JSON string. So far it seems to be much more of a daunting task than it should be. Since I'm using Entity the data comes back nicely to me as an IEnumerable. Now I believe I just need some form of recursion, but I'm not quite sure where to start. Any help is appreciated.
Data Returns as
id parentId name
1 1 TopLoc
2 1 Loc1
3 1 Loc2
4 2 Loc1A
Code is
public static string GetJsonLocationHierarchy(long locationID)
{
using (EntitiesSettings context = new EntitiesSettings())
{
// IEnumerable of ID,ParentID,Name
context.GetLocationHierarchy(locationID);
}
}
The end result I'd hope would be something like this:
{
"id": "1",
"parentId": "1",
"name": "TopLoc",
"children": [
{
"id": "2",
"parentId": "1",
"name": "Loc1",
"children": [
{
"id": "4",
"parentId": "2",
"name": "Loc1A",
"children": [
{}
]
}
]
},
{
"id": "3",
"parentId": "1",
"name": "Loc2",
"children": [
{}
]
}
]
}
One way to turn a flat table into a hierarchy is to put all your nodes into a dictionary. Then iterate over the dictionary, and for each node, look up its parent and add it to the parent's children. From there, you just need to find the root and serialize it.
Here is an example program to demonstrate the approach:
class Program
{
static void Main(string[] args)
{
IEnumerable<Location> locations = new List<Location>
{
new Location { Id = 1, ParentId = 1, Name = "TopLoc" },
new Location { Id = 2, ParentId = 1, Name = "Loc1" },
new Location { Id = 3, ParentId = 1, Name = "Loc2" },
new Location { Id = 4, ParentId = 2, Name = "Loc1A" },
};
Dictionary<int, Location> dict = locations.ToDictionary(loc => loc.Id);
foreach (Location loc in dict.Values)
{
if (loc.ParentId != loc.Id)
{
Location parent = dict[loc.ParentId];
parent.Children.Add(loc);
}
}
Location root = dict.Values.First(loc => loc.ParentId == loc.Id);
JsonSerializerSettings settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(root, settings);
Console.WriteLine(json);
}
}
class Location
{
public Location()
{
Children = new List<Location>();
}
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
public List<Location> Children { get; set; }
}
Here is the output:
{
"id": 1,
"parentId": 1,
"name": "TopLoc",
"children": [
{
"id": 2,
"parentId": 1,
"name": "Loc1",
"children": [
{
"id": 4,
"parentId": 2,
"name": "Loc1A",
"children": []
}
]
},
{
"id": 3,
"parentId": 1,
"name": "Loc2",
"children": []
}
]
}

Categories