Customise Default Output Of JSON in MVC C# - c#

I am using dynamic ExpandoObject() to create some json required for an NVD3/d3.js visualisation.
The nvd3 library is pretty explicit in what it needs with regards to data identifiers.
Exactly the json i need is the following -
[{
key: "AgeGroups",
values: [{
"label": "<20",
"value": 0
}, {
"label": ">20 <29",
"value": 160
}, {
"label": ">29 <39",
"value": 240
}]
}]
Note: the string 'key' must be lowercase and values must be pluralized.
With the following c#, I am able to get very close -
ageDemoJson.AgeGroups = new object[]
{
new { label = "<20", value = lessThan20 },
new { label = ">20 <29", value = between20and29 },
new { label = ">29 <39", value = between29and39 },
};
This outputs the following
[{
Key: "AgeGroups",
Value: [{
"label": "<20",
"value": 0
}, {
"label": ">20 <29",
"value": 160
}, {
"label": ">29 <39",
"value": 240
}]
}]
With this output, I need to customise the default behaviour of ExpandoObject and make the string 'Key' become 'key' and the string 'value' become 'values'
Is there anyway of doing this?
Of course I can work around this by parsing the json to string and replacing what I need in javascript, but would like if I didn't have to do that.

If you're using asp.net core you can change the JSON serialization by adding this line:
services.AddMvc()
.AddJsonOptions(opts =>
{
// Force Camel Case to JSON
opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
Or you can achive the same result by using Newtonsoft's Json.NET with this option:
string json = JsonConvert.SerializeObject(
yourObjectToSerialize,
new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
);

Related

Reformatting a JSON in C#

I have a JSON response here,
{
"Items": [
{
"Key": {
"timestamp": "2022-11-06T20",
"value": 100.80
}
},
{
"Key": {
"timestamp": "2022-11-07T08",
"value": 100.90
}
}
]
}
That I would like to reformat to this:
{
"Key": [
{
"timestamp": "2019-01-08T20",
"value": 12.44
},
{
"timestamp": "2018-12-12 16:23:00",
"value": 12.45
}
]
}
For all responses, the Key must only be on the top once followed by an array of timestamps and values, and remove the Items parent value completely. I have tried doing this and messing around with the implementation, but I keep receiving multiple different errors. Is this the correct idea to do it or is there a better way to implement this?
JObject obj = JObject.Parse(jsonOutput);
JObject newObj = new JObject();
new JProperty("KEY", new JArray(
.Children<JProperty>()
.Select(j => new JObject(
new JProperty("timestamp", j.Value["timestamp"]),
new JProperty("value", j.Value["value"])
)
)
)
);
jsonOutput = newObj.ToString();
What is the correct way to implement this idea? Thanks!
This can be done very easily by combining
SelectTokens() with a JSONPath wildcard operator for the Items[*] array to select all required JSON objects.
Serialization of an anonymous type object to create the required output structure.
Thus:
var query = obj.SelectTokens("Items[*].Key");
jsonOutput = JsonConvert.SerializeObject(new { Key = query }, Formatting.Indented);
Demo fiddle here.
you can fixed it in one line
jsonOutput = new JObject {new JProperty("Key", ((JArray)JObject.Parse(jsonOutput)
["Items"]).Select(s => s["Key"]))}.ToString();

Deserializing random json file in c#

i am trying to take in a json file and iterate over some of the values.
The file is 73000 lines long, and i only need a few values.
Here is an example of the json file:
{
"value" : "key"
"value" : "key"
"Owner": {
"UserId": xxx,
"Username": "xxx",
},
"Items": [
{
"value": "key",
"value": "key",
"Comment": "",
"value": {
"value": {
"value": "key",
"value": "key",
"value": "key",
}
},
"CustomFields": [
{
"Name": "something",
"Content": "true"
}
]
}
]
}
How do i load this in without defining the object? i need 5 values per item, from different nesting levels, though i dont want to define the class as the file is more than 70.000 lines.
I tried doing it like this:
var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
But that way i will get an error when i try to itterate over items, as items value will now be a string!
foreach (Dictionary<string, string> result in values["items"])
Is there a way to load the file, defining the class based on the json schema?
I need values from different levels in the file, some at root level some nested.

Transform a JSON object to a JSON array, taking the first level of properties

I've this JSON object
{
"08f4f705-6e14-4781-8241-d04bf2dc6ada": {
"description": "xxxxxxxx",
"note": "yyyyyyyy"
},
"05f4f995-6e14-4567-8241-d04bf2d456ee": {
"description": "aaaaaa",
"note": "bbb"
},
"0675f995-6e14-4567-8241-d4567f2d456z": {
"description": "fffff",
"note": "gggg"
}
}
I need to convert into a JSON array like this:
(the elements should be the content of the first level properties)
[
{
"description": "xxxxxxxx",
"note": "yyyyyyyy"
},
{
"description": "aaaaaa",
"note": "bbb"
},
{
"description": "fffff",
"note": "gggg"
}
]
I can't manipulate the object and I didn't find an appropriate resource to follow. How can I do it?
You can achieve this by deserializing your json string into Dictionary<string, object>:
var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
After that you extract the values and serialize them back to json:
var newJson = JsonConvert.SerializeObject(obj.Values);

mongodb c# how to work with BSON document

I've spent MANY hours looking for the answer...
This is very easy in PHP but I just can't put it together in C#(I'm new to C# and mongo...)
I'm trying to iterate through all levels of a stored document. The document looks like this:
{
"_id": ObjectId("51f90101853bd88971ecdf27"),
"fields": [
{
"ID": ObjectId("51fd09498b080ee40c00514e"),
"NAME": "ID",
"TYPE": "Text"
},
{
"ID": ObjectId("51fd09a68b080ee40c0064db"),
"NAME": "Title",
"TYPE": "Text"
},
{
"ID": ObjectId("51fd09b28b080ee40c004d31"),
"NAME": "Start Date",
"TYPE": "Date"
},
{
"ID": ObjectId("51fd09c28b080ee40c007f2e"),
"NAME": "Long Description",
"TYPE": "Memo"
}
],
"name": "TODB",
"updated": "Wed Jul 31 2013 08:20:17 GMT-0400 (Eastern Daylight Time)"
}
I have no problem accessing the "name" and "updated" but can't figure out how to access the "fields" array.
Code so far :
{
MongoServer mongo = MongoServer.Create();
mongo.Connect();
var db = mongo.GetDatabase("forms");
mongo.RequestStart(db);
var collection = db.GetCollection("forms");
var query = new QueryDocument("name",
"TODB");
mongo.Disconnect();
}
#foreach(BsonDocument item in collection.Find(query))
{
#item.GetElement("name").Value
#item.GetElement("_id").Value
}
Again, I am able to access the name and _id just not any of the sub document values.
Thanks in advance for any assistance!
After I get the reading figured out, I am also going to want to write data....
There are a few ways, but here's one:
// build some test data
BsonArray dataFields = new BsonArray { new BsonDocument {
{ "ID" , ObjectId.GenerateNewId()}, { "NAME", "ID"}, {"TYPE", "Text"} } };
BsonDocument nested = new BsonDocument {
{ "name", "John Doe" },
{ "fields", dataFields },
{ "address", new BsonDocument {
{ "street", "123 Main St." },
{ "city", "Madison" },
{ "state", "WI" },
{ "zip", 53711}
}
}
};
// grab the address from the document,
// subdocs as a BsonDocument
var address = nested["address"].AsBsonDocument;
Console.WriteLine(address["city"].AsString);
// or, jump straight to the value ...
Console.WriteLine(nested["address"]["city"].AsString);
// loop through the fields array
var allFields = nested["fields"].AsBsonArray ;
foreach (var fields in allFields)
{
// grab a few of the fields:
Console.WriteLine("Name: {0}, Type: {1}",
fields["NAME"].AsString, fields["TYPE"].AsString);
}
You can often use the string indexer ["name-of-property"] to walk through the fields and sub document fields. Then, using the AsXYZ properties to cast the field value to a particular type as shown above.

JSON nested array

Lets say i have the following JSON
{
"data": [
{
"from": {
"name": "aaa bbb",
},
"actions": [
{
"name": "Comment",
"link": "http://...
},
{
"name": "Like",
"link": "http://.."
}
],
},
And i have
JSONObject wallData = helper.Get("/me/feed");
if (wallData != null)
{
var data = wallData.Dictionary["data"];
List<JSONObject> wallPosts = data.Array.ToList<JSONObject>();
}
foreach (Facebook.JSONObject wallItem in wallPosts)
{ ... }
Which stores me whole feed into wallData and 'data' object into wallPosts.
So then i can access the wallItem.Dictionary["from"].Dictionary["name"], and i get "aaa bbb".
But i can't get inside the actions array
The wallItem.Dictionary["actions"].Dictionary["name"] doesn't work.
Any idea
You need to do something like wallItem.Dictionary["actions"][0].Dictionary["name"] because "actions" is an array.
On a different note...its neater if u directly into a class...like this
var jSerializer = new JavaScriptSerializer();
var jsonObject = jSerializer.Deserialize<DataObject>(json);
The DataObject will be a class which emulates ur JSON data in a strongly typed class. Depending on the size of ur Json you will not have to use a lot of strings in your code.

Categories

Resources