Is there a way to update JSON key name or Change the existing Keyname of a json?
class NewBands
{
private List<NSongs> _NBandName;
public string NewBandName { get; set; }
public List<NSongs> NBandName
{
get { return _NBandName; }
set { _NBandName = value; }
}
}
class NSongs
{
public string NSongTitle { get; set; }
}
[HttpPost]
public JsonResult Bands()
{
dbBandsEntities dbband = new dbBandsEntities();
var returnjson = dbband.Bands.AsEnumerable().Select(x => new NewBands()
{
NewBandName = x.BandName.ToString(),
NBandName = dbband.BandSongs.AsEnumerable().Where(y => y.BandId == x.Id).Select(z => new NSongs() {
NSongTitle = z.SongTitle
}).ToList()
});
return Json(returnjson, JsonRequestBehavior.AllowGet);
}
Output:
[ {
"NewBandName": "Amber Pacific",
"NBandName": [
{ "NSongTitle": "Fall Back Into My Arms" },
{ "NSongTitle": "If I Fall" },
{ "NSongTitle": "When I Found You" }
] }, {
"NewBandName": "Mayday Parade",
"NBandName": [
{ "NSongTitle": "Misserable at Beast" },
{ "NSongTitle": "The Problem with Big Picture is I can't see" }
] }, {
"NewBandName": "Fm Static",
"NBandName": [
{ "NSongTitle": "Dear God" },
{ "NSongTitle": "Her Father Songs" },
{ "NSongTitle": "Last Train Home" },
{ "NSongTitle": "Tonight" },
{ "NSongTitle": "Black Tattoo" }
] }
I Want to update NBandName to BandName Itself.
Output should be:
{
"NewBandName": "Amber Pacific",
"Amber Pacific": [
{ "NSongTitle": "Fall Back Into My Arms" },
{ "NSongTitle": "If I Fall" },
{ "NSongTitle": "When I Found You" }
]
}......
Instead of creating a list of NewBands objects you may create a list of dictionaries of string keys and object values. This allows to set arbitrary key names on the fly:
var returnjson = dbband.Bands.AsEnumerable().Select(x => new Dictionary<string, object>
{
{ "NewBandName", x.BandName.ToString() },
{
x.BandName.ToString(),
dbband.BandSongs
.AsEnumerable()
.Where(y => y.BandId == x.Id)
.Select(z => new NSongs() {
NSongTitle = z.SongTitle
})
.ToList()
}
});
Related
I have json text like this:
{
"course_editions": {
"2014/SL": [
{
"grades": {
"course_units_grades": {
"159715": {
"1": {
"value_symbol": "4",
"exam_session_number": 1,
"exam_id": 198172,
"value_description": {
"en": "good",
}
}
}
},
"course_grades": {}
}
},
{
"grades": {
"course_units_grades": {
"159796": {
"1": {
"value_symbol": "5",
"exam_session_number": 1,
"exam_id": 198259,
"value_description": {
"en": "very good",
}
}
}
},
"course_grades": {}
}
},
I would like to use JToken.SelectTokens Method from Namespace: Newtonsoft.Json.Linq
I've tried like this:
string json_response = GetResponse(sign(url_courses));
var courses_tokens = JObject.Parse(json_response).SelectTokens("['course_editions'].['2014/SL'].[*].['grades'].*")
It doesn't work. I would like to get only these numbers after course_unit_grades and before "1". So in this example only: "159715" and "159796" to be able to use all of them, one by one in
foreach(var lp in courses_tokens) {
}
This is one possible way :
var jobj = JObject.Parse(json);
var coursesTokens = jobj.SelectTokens("course_editions.2014/SL[*].grades.course_units_grades")
.Select(o => o.First) //get the first child of `course_units_grades`
.Cast<JProperty>() //cast to JProperty
.Select(o => o.Name); //get the name of the property
foreach (string coursesToken in coursesTokens)
{
Console.WriteLine(coursesToken);
}
Dotnetfiddle Demo
given json sample at the bottom, the output is as follow :
159715
159796
json sample :
var json = #"{
'course_editions': {
'2014/SL': [
{
'grades': {
'course_units_grades': {
'159715': {
'1': {
'value_symbol': '4',
'exam_session_number': 1,
'exam_id': 198172,
'value_description': {
'en': 'good'
}
}
}
},
'course_grades': {}
}
},
{
'grades': {
'course_units_grades': {
'159796': {
'1': {
'value_symbol': '5',
'exam_session_number': 1,
'exam_id': 198259,
'value_description': {
'en': 'very good'
}
}
}
},
'course_grades': {}
}
}
]
}
}";
Given 2 JSON strings:
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryC",
"description":"CategoryC"
},
{
"id":"CategoryD",
"description":"CategoryD"
},
{
"id":"CategoryE",
"description":"CategoryE"
},
{
"id":"CategoryF",
"description":"CategoryF"
},
{
"id":"CategoryG",
"description":"CategoryG"
},
{
"id":"CategoryH",
"description":"CategoryH"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
}
]
AND
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryB",
"description":"CategoryB"
}
]
}
]
First one is the original. The second are the values that I want to remove from the original. So basically, if there is a match on brand and category between first and second JSON, regardless of the order of the elements, I want that match to be removed.
The expected result would be someting like this:
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryD",
"description":"CategoryD"
},
{
"id":"CategoryE",
"description":"CategoryE"
},
{
"id":"CategoryF",
"description":"CategoryF"
},
{
"id":"CategoryG",
"description":"CategoryG"
},
{
"id":"CategoryH",
"description":"CategoryH"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
}
]
Catagory A and C in Brand A were removed as well as Category B in Brand B.
Based in some research, I was using https://github.com/wbish/jsondiffpatch.net, tried to work with it's functions, but so far I didn't manage to achieve the result I want. Also, to solve this by processing JSON direcly is not a must. If there is a simpler solution to achieve that by converting them to lists and use something like LINQ for example, it works for me as well (tried that, but didn't manage to find a way to do this comparison).
Thanks in advance.
If performance does not matter, the JsonSerializer and LINQ can be used:
Model
public class JsonModel
{
public class ValueModel
{
public string Id { get; set; }
public string Description { get; set; }
}
public string Id { get; set; }
public string Description { get; set; }
public IEnumerable<ValueModel> Values { get; set; }
}
Deserialize and LINQ
string json1Str = #"[...]";
string json2Str = #"[...]";
var opt = new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var json1 = System.Text.Json.JsonSerializer.Deserialize<List<JsonModel>>(json1Str, opt);
var json2 = System.Text.Json.JsonSerializer.Deserialize<List<JsonModel>>(json2Str, opt);
var result = json1.
Join(json2, j1 => j1.Id, j2 => j2.Id, (j1, j2) => new JsonModel
{
Id = j1.Id,
Description = j1.Description,
Values = j1.Values.Where(j1 => !j2.Values.Select(val => val.Id).Contains(j1.Id))
});
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(result, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }));
}
Result
[
{
"Id": "BA",
"Description": "BrandA",
"Values": [
{
"Id": "CategoryB",
"Description": "CategoryB"
},
{
"Id": "CategoryD",
"Description": "CategoryD"
},
{
"Id": "CategoryE",
"Description": "CategoryE"
},
{
"Id": "CategoryF",
"Description": "CategoryF"
},
{
"Id": "CategoryG",
"Description": "CategoryG"
},
{
"Id": "CategoryH",
"Description": "CategoryH"
}
]
},
{
"Id": "BB",
"Description": "BrandB",
"Values": [
{
"Id": "CategoryA",
"Description": "CategoryA"
},
{
"Id": "CategoryC",
"Description": "CategoryC"
}
]
}
]
I have below JSON which I have de-serialized into a C# object and would like to extract the values of INFO_CARD_ID, DOCUMENT_NUM and REVISION_NM at each iteration.
{
"result": {
"message": "Successfully performed search",
"columnlist": "INFO_CARD_ID,DOCUMENT_NUM,REVISION_NM,
"recordcount": 2,
"rows": [
{
"columns": [
{
"value": "UJ3P25HO3JBPLJZ2HU",
"key": "INFO_CARD_ID"
},
{
"value": "DOC1",
"key": "DOCUMENT_NUM"
},
{
"value": "05",
"key": "REVISION_NM"
}
]
},
{
"columns": [
{
"value": "JWQ5TCIV4JC2BCQ4C5",
"key": "INFO_CARD_ID"
},
{
"value": "DOC2",
"key": "DOCUMENT_NUM"
},
{
"value": "05",
"key": "REVISION_NM"
}
]
}
]
}
}
Here are the C# classes:
public class Columns
{
public string value { get; set; }
public string key { get; set; }
}
public class Rows
{
public IList<Columns> columns { get; set; }
}
public class Result
{
public string message { get; set; }
public string columnlist { get; set; }
public int recordcount { get; set; }
public IList<Rows> rows { get; set; }
}
public class searchOutputModel
{
public Result result { get; set; }
}
So far, I have been trying to extract the information on a list with below expression but with no luck, as the individual value is getting stored on each iteration and not all the values at each iteration at the same time.
searchResponse = JsonConvert.DeserializeObject<searchOutputModel>(json);
var dynamicList = searchResponse.result.rows.SelectMany(x => x.columns).Where(y => y.key.Contains("INFO_CARD_ID") || y.key.Contains("DOCUMENT_NUM") || y.key.Contains("REVISION_NM")).Select(y => {
dynamic myValue;
if (y.key.Contains("INFO_CARD_ID"))
myValue = new { INFO_CARD_ID = y.value };
else if (y.key.Contains("DOCUMENT_NUM"))
myValue = new { DOCUMENT_NUM = y.value };
else
myValue = new { REVISION_NM = y.value };
return myValue;
}).ToList();
Expected output:
INFO_CARD_ID DOCUMENT_NUM REVISION_NM
---------------------------------------------
UJ3P25HO3JBPLJZ2HU DOC1 05
JWQ5TCIV4JC2BCQ4C5 DOC2 05
I know I am doing wrong with iteration as it creates new list at each select, but I am not sure how can I achieve the solution that I am looking for. Any help is appreciated.
We just need to select one object per row, no need for SelectMany here. Each property can be gotten by using columns.FirstOrDefault.
I would advise you to create a proper class for this rather than using dynamic but it makes little difference to the logic below.
Not sure why you used Contains on the column.key check, I've used ==
var dynamicList = searchResponse.result.rows.Select(r =>
new {
INFO_CARD_ID = r.columns.FirstOrDefault(c => c.key == "INFO_CARD_ID")?.value,
DOCUMENT_NUM = r.columns.FirstOrDefault(c => c.key == "DOCUMENT_NUM")?.value,
REVISION_NM = r.columns.FirstOrDefault(c => c.key == "REVISION_NM")?.value,
}).ToList();
If you convert each Rows object to a Dictionary, you can use the Dictionary to create objects:
var ans = searchResponse.result.rows
.Select(r => r.columns.ToDictionary(c => c.key, c => c.value))
.Select(cd => new {
INFO_CARD_ID = cd["INFO_CARD_ID"],
DOCUMENT_NUM = cd["DOCUMENT_NUM"],
REVISION_NM = cd["REVISION_NM"]
});
I have some JSON data that looks like this:
[
{
"name": "foo",
"id": 1,
"child": {
name: "A",
id: 1,
}
},
{
"name": "bar",
"id": 1,
"child": {
name: "A",
id: 1,
}
},
{
"name": "baz",
"id": 2,
"child": {
name: "B",
id: 2,
}
},
{
"name": "alpha",
"id": 1,
"child": {
name: "A",
id: 1,
}
}
]
I'm loading it into my .NET project and trying to restructure it so that it returns a response that looks something like this:
[
{
"name": "A"
"id": 1,
"parents": [
{
"name": "foo",
"id": 1,
},
{
"name": "bar",
"id": 1,
},
{
"name": "alpha",
"id": 1,
}
]
},
{
"name": "B"
"id": 2,
"parents": [
{
"name": "baz",
"id": 2,
}
]
}
]
I was able to use LINQ to grab all the IDs that matched, but only for 1 ID.
var test = deserializedJsonData.Where(w => w.child.id == SomeID).Select(s => s).ToList()
The moment I tried to iterate "SomeID" inside of a loop to iterate it, it freezes and crashes.
Is there a more efficient way of doing this?
EDIT: Corrected typo as pointed out in comments
Regarding your requirement, I've created the objects.
public class Base
{
public int id { get; set; }
public string name { get; set; }
}
public class Data : Base
{
public Base child { get; set; }
}
public class RequiredData : Base
{
public List<Base> parents { get; set; }
}
Then created a comparer to distinct your child objects.
public class BaseComparer : IEqualityComparer<Base>
{
public bool Equals(Base x, Base y)
{
if (x.id.Equals(y.id) && (x.name.Equals(y.name)))
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(Base obj)
{
unchecked
{
int hash = 100;
hash = hash * 10 + obj.id.GetHashCode();
hash = hash * 10 + obj.name.GetHashCode();
return hash;
}
}
}
Finally,
string rawData = File.ReadAllText(#"your_json_file_path");
var parsedData = JsonConvert.DeserializeObject<Data[]>(rawData);
var childs = parsedData.GroupBy(g => g.child.id).Select(s => new Base()
{
id = s.Key,
name = s.Where(w => w.child.id == s.Key).First().child.name
}).ToList();
var result = parsedData.GroupBy(s => s.child).Select(s =>
new RequiredData()
{
id = s.Key.id,
name = s.Key.name,
parents = parsedData.Where(w => w.child.id == s.Key.id).Select(x =>
new Base()
{
id = x.id,
name = x.name
}).ToList()
}).Distinct(new BaseComparer()).ToList();
var jsonResult = JsonConvert.SerializeObject(result);
jsonResult will contain your required output.
Note: I'm using Newtonsoft.Json library for JSON operations.
I have json text like this:
{
"course_editions": {
"2014/SL": [
{
"grades": {
"course_units_grades": {
"159715": {
"1": {
"value_symbol": "4",
"exam_session_number": 1,
"exam_id": 198172,
"value_description": {
"en": "good",
}
}
}
},
"course_grades": {}
}
},
{
"grades": {
"course_units_grades": {
"159796": {
"1": {
"value_symbol": "5",
"exam_session_number": 1,
"exam_id": 198259,
"value_description": {
"en": "very good",
}
}
}
},
"course_grades": {}
}
},
I would like to use JToken.SelectTokens Method from Namespace: Newtonsoft.Json.Linq
I've tried like this:
string json_response = GetResponse(sign(url_courses));
var courses_tokens = JObject.Parse(json_response).SelectTokens("['course_editions'].['2014/SL'].[*].['grades'].*")
It doesn't work. I would like to get only these numbers after course_unit_grades and before "1". So in this example only: "159715" and "159796" to be able to use all of them, one by one in
foreach(var lp in courses_tokens) {
}
This is one possible way :
var jobj = JObject.Parse(json);
var coursesTokens = jobj.SelectTokens("course_editions.2014/SL[*].grades.course_units_grades")
.Select(o => o.First) //get the first child of `course_units_grades`
.Cast<JProperty>() //cast to JProperty
.Select(o => o.Name); //get the name of the property
foreach (string coursesToken in coursesTokens)
{
Console.WriteLine(coursesToken);
}
Dotnetfiddle Demo
given json sample at the bottom, the output is as follow :
159715
159796
json sample :
var json = #"{
'course_editions': {
'2014/SL': [
{
'grades': {
'course_units_grades': {
'159715': {
'1': {
'value_symbol': '4',
'exam_session_number': 1,
'exam_id': 198172,
'value_description': {
'en': 'good'
}
}
}
},
'course_grades': {}
}
},
{
'grades': {
'course_units_grades': {
'159796': {
'1': {
'value_symbol': '5',
'exam_session_number': 1,
'exam_id': 198259,
'value_description': {
'en': 'very good'
}
}
}
},
'course_grades': {}
}
}
]
}
}";