How to extract a dataset from Json where the element is fluid - c#

I have a Json object coming into my WebApi. The structure can take any form. The only thing I know for certain is that somewhere in that structure (could be a top level node, could be a child node) I will have a node made up of:
"data": {
"mop": "1012346354462",
"fuelType": "E",
"Id": "1029dd56-10b1-46cb-9966-3c37e057a470",
"Status": "SecuredActive",
"StatusFromDate": "2020-11-20T17:00:00.000Z",
"ActiveDate": "2020-11-21T00:00:00.000Z",
"GeneratedReference": "1012346354462_1"
},
Can anyone help on how I can easily extract this bit of data from the JSon Object. I have a class that maps to these properties, but before I can use it I need to single this out from the rest of the JSON. I'm using C#

After much playing around, I've finally found a solution, so thought I'd post in-case others hit a similar issue.
JObject result = JObject.Parse(Request.ToString());
var clientarray = result["events"].Value<JArray>();
var blockIwant = clientarray.Children<JObject>().Select(x => x.Children<JProperty>().Where(y => y.Name == "data").First());

use JSON Convert to deserialize the object.
var Data = JsonConvert.DeserializeObject<dynamic>(data);
Then you can access using the Data object.
Eg : Console.WriteLine((String)Data.data.fuelTypereturn);
Gives the answer as "E"

Related

How to check In C# JArray have specific key pair

I am working on JArray in .NET CORE and I am getting random structure of this one specific key, hence getting different error. I need to know if JArray has specific child Array and if Child JArray have specific key pair (NOT VALUE) i.e. value{ "Id":""} one of error is following;
Accessed JArray values with invalid key value: "id". Int32 array index expected.
at Newtonsoft.Json.Linq.JArray.get_Item(Object key) at
the standard structure I am expecting is as following;
{[value, [
{
"id": "7ef82869-e235-69a2-f81e-3a9664e89bc4",
"value": ""
}
]]}
sometime I get as, meaning throw null error where I am trying to map Id.
{[value, [
{
"value": ""
}
]]}
and some Time I don't get this property at all
I am trying following check to cover all scenario but Its not really working.
code
if (answerItems.value != null && answerItems.value.HasValues && answerItems.value["id"]!=null)
{
I received some constructive criticism on the brevity of my answer so I figured I would elaborate to help you through your issue.
First, let's take a look at your JSON. In short, it isn't valid. In fact, it isn't even close to valid JSON. I can only assume you meant something like this:
{
"values" : [{ "id" : "7ef82869-e235-69a2-f81e-3a9664e89bc4", "value": "" }]
}
I would suggest that anytime you are trying to parse data like this and you run into issues you start trouble shooting by validating the data itself. I like to use JSONLint for this.
Next, it is difficult from your example code to tell exactly what you are trying to do. I can only guess that you are attempting to use the dynamic object method of parsing and working with the data. A downside to this method is it is difficult to validate your data before you work with it.
Instead, I would use the Newtonsoft.Json.Linq.JObject.Parse method. This gives you some tools for working with and validating the information. Below I have included a very simple example of how this would be done.
using System;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
string json = "{ \"values\": [{ \"id\": \"7ef82869-e235-69a2-f81e-3a9664e89bc4\", \"value\": \"\" }] }";
JObject obj = JObject.Parse(json);
// Check to see if we got our value array
if (obj.ContainsKey("values")) {
JArray values = (JArray)obj["values"];
// Do we have any values in our array?
if (values.Count > 0) {
JObject firstItem = (JObject)values[0];
// We check to see if we have an ID parameter
if (firstItem.ContainsKey("id")) {
Console.WriteLine(firstItem["id"]);
}
}
}
}
}
As I mentioned in my original post, I would strongly recommend reviewing the Newtonsoft.Json documentation.

JContainer, JObject, JToken and Linq confusion

I am having trouble understanding when to use JContainer, JObject, and JToken. I understand from the "standards" that JObject is composed of JProperties and that JToken is the base abstract class for all of the JToken types, but I don't understand JContainer.
I am using C# and I just bought LinqPad Pro 5.
I have a JSON data source in a file, so I'm deserializing that file's contents successfully using this statement:
string json;
using (StreamReader reader = new StreamReader(#"myjsonfile.json"))
{
json = reader.ReadToEnd();
}
At that point, I take the JSON string object and deserialize it to a JObject (and this might be my mistake--perhaps I need to make jsonWork a JToken or JContainer?):
JObject jsonWork = (JObject)JsonConvert.DeserializeObject(json);
In my JSON data (the string represented by JSON), I have three objects--the top-level object look similar to this:
{
"Object1" : { ... },
"Object2" : { ... },
"Object3" : { ... }
}
Each object is composed of all sorts of tokens (arrays, strings, other objects, etc.), so it is dynamic JSON. (I used ellipses as placeholders rather than muddying up this question wit lots of JSON data.)
I want to process "Object1", "Object2", and "Object3" separately using LINQ, however. So, ideally, I would like something like this:
// these lines DO NOT work
var jsonObject1 = jsonWork.Children()["Object1"]
var jsonObject2 = jsonWork.Children()["Object2"]
var jsonObject3 = jsonWork.Children()["Object3"]
But the above lines fail.
I used var above because I have no idea what object type I should be using: JContainer, JObject, or JToken! Just so you know what I want to do, once the above jsonObject# variables are properly assigned, I would like to use LINQ to query the JSON they contain. Here is a very simple example:
var query = from p in jsonObject1
where p.Name == "Name1"
select p
Of course, my LINQ ultimately will filter for JSON arrays, objects, strings, etc., in the jsonObject variable. I think once I get going, I can use LinqPad to help me filter the JSON using LINQ.
I discovered that if I use:
// this line WORKS
var jsonObject1 = ((JObject)jsonWork).["Object1"];
Then I get an JObject type in jsonObject1. Is this the correct approach?
It is unclear to me when/why one would use JContainer when it seems that JToken and JObject objects work with LINQ quite well. What is the purpose of JContainer?
You don't really need to worry about JContainer in most cases. It is there to help organize and structure LINQ-to-JSON into well-factored code.
The JToken hierarchy looks like this:
JToken - abstract base class
JContainer - abstract base class of JTokens that can contain other JTokens
JArray - represents a JSON array (contains an ordered list of JTokens)
JObject - represents a JSON object (contains a collection of JProperties)
JProperty - represents a JSON property (a name/JToken pair inside a JObject)
JValue - represents a primitive JSON value (string, number, boolean, null)
So you see, a JObject is a JContainer, which is a JToken.
Here's the basic rule of thumb:
If you know you have an object (denoted by curly braces { and } in JSON), use JObject
If you know you have an array or list (denoted by square brackets [ and ]), use JArray
If you know you have a primitive value, use JValue
If you don't know what kind of token you have, or want to be able to handle any of the above in a general way, use JToken. You can then check its Type property to determine what kind of token it is and cast it appropriately.
JContainer is a base class for JSON elements that have child items. JObject, JArray, JProperty and JConstructor all inherit from it.
For example, the following code:
(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")
Would throw an InvalidCastException, but if you cast it to a JContainer, it would be fine.
Regarding your original question, if you know you have a JSON object at the top level, you can just use:
var jsonWork = JObject.Parse(json);
var jsonObject1 = jsonWork["Object1"];
Most examples have simple json and I've googled "C# Newtonsoft parse JSON" more than once.
Here's a bit of a json file I was just asked to parse for a csv. The company name value is nested within many arrays / objects so it is semi-complicated in that regard.
{
"page": {
"page": 1,
"pageSize": 250
},
"dataRows": [
{
"columnValues": {
"companyName": [
{
"name": "My Awesome Company",
}
]
}
}
]
}
var jsonFilePath = #"C:\data.json";
var jsonStr = File.ReadAllText(jsonFilePath);
// JObject implementation for getting dataRows JArray - in this case I find it simpler and more readable to use a dynamic cast (below)
//JObject jsonObj = JsonConvert.DeserializeObject<JObject>(jsonStr);
//var dataRows = (JArray)jsonObj["dataRows"];
var dataRows = ((dynamic)JsonConvert.DeserializeObject(jsonStr)).dataRows;
var csvLines = new List<string>();
for (var i = 0; i < dataRows.Count; i++)
{
var name = dataRows[i]["columnValues"]["companyName"][0]["name"].ToString();
// dynamic casting implemntation to get name - in this case, using JObject indexing (above) seems easier
//var name2 = ((dynamic)((dynamic)((dynamic)dataRows[i]).columnValues).companyName[0]).name.ToString();
csvLines.Add(name);
}
File.WriteAllLines($#"C:\data_{DateTime.Now.Ticks}.csv", csvLines);

Deserialize complex JSON data in C#

I'm just an amateur in C# programming. Now i have a JSON data that looks like following
{
type: "xxx",
width: "xxx",
dataSource: {
"chart": {
"caption": "xxx"
},
"data": [
{},
{}
]
}
}
I'm having the whole data as escaped string. now after Unescape when I'm using JavaScriptSerializer as follows
var data = ser.Deserialize<Dictionary<String, Object>>(chartData);
I'm able to get the "type", "width" as
data["width"]
data["type"]
Now I have to get the value of "caption". Any suggestion how to get that, I believe the dictionary structure need to be changed but I'm stacked for my lack of knowledge in C#
If you know the object's scheme you man want to create a class that represents in and then deserialize the json into it:
YourKnownClass obj = JsonConvert.DeserializeObject<YourKnownClass>(json);
Console.WriteLine(obj.dataSource.chart.caption.Value);
Another option is by using a dynamic type (There is no good reason using a dynamic object if you know the schema and can create a matching C# class. This has a performance impact as well):
dynamic obj = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine(obj.dataSource.chart.caption.Value);
BTW, In this example i'm using json.net which is a popular library.

JSON.net parent key

I'm having a hard time getting the parent key/property/attribute of my JSON objects using JSON.net. That is, I want the outermost property name, as a string, without knowing beforehand/visually what it is. I'm currently iterating over a set of KeyValuePair items and attempting to, for each of those, log out the parent from something that looks like
{"parentKey":
{
"Name": "Name",
"Id": "123",
"Other": null,
"nestedArr":
[
"idx0",
"idx1",
"idx2"
]
}
}
I've tried both keyValue.Value.Ancestors() and keyValue.Value.Parent. With the former, I'm getting what looks to be the function definition... I'm actually not sure what it is: Newtonsoft.Json.Linq.JToken+<GetAncestors>d_ _ 42. Completely beffuddled by that, because based on the usage examples I've scrounged up here, I'm using it to standard.
With the latter, I log out the entire object, or else what appears to be the entire preceding KeyValuePair, rather than just the string "parentKey", which is what I want. The JSON.net docs aren't the best as far as explicit usage examples and what to expect (or maybe it's just that being new to C#, I can't make sense of them), but in any case, I'm kind of unclear on why this is happening and how to accomplish what I want. This is what I'm trying:
foreach (var keyValue in jObjList[0]) //jObjList is a List<JObject> defined above
{
Console.WriteLine(keyValue.Value.Ancestors());
Console.WriteLine(keyValue.Value.Parent);
if (keyValue.Value.GetType() == typeof(JObject))//same block goes for if it's typeof(JArray)
{
Console.WriteLine(keyValue.Key);
}
}
Edit: in the JSON given, and within the loop defined above, for example, in order to get my parent keys (that's just what I'm calling them), my code simply says, if (keyValue.Value.GetType() == typeof(JObject), write keyValue.Key to the console, and the same goes for if getType() is a JArray. In either case, keyValue.Key is a parent key, if that makes sense. What I mean to say by this is that it is a property that points to another Array or Object. My issue is that, as I'm doing this loop recursively, when I get down to a nested Array or Object, my code has no way of realizing that, although there is a new "parent key" currently, like with nestedArr, for example, the parent key of nestedArr is still "parentKey".
the code is abridged, but that's the idea.
All clarifications and corrections are welcome and appreciated. Thanks.
You are seeing Newtonsoft.Json.Linq.JToken+<GetAncestors>d_ _ 42 for Console.WriteLine(keyValue.Value.Ancestors()) because Ancestors is an IEnumerable<T> whose evaluation is lazy, rather than an explicit collection. What you are seeing is the ToString() output of the not-yet-evaluated enumerable.
If what you want to do is to climb up the parent list of a given JToken and find the lowest parent that has a "parentKey" property, then get the value of that parentKey, then this is how you would do it:
JToken token = keyValue.Value; // Here I'm declaring JToken explicitly for clarity. Normally I would use var token = ...
var parentKey = token.AncestorsAndSelf() // Climb up the json container parent/child hierachy
.Select(p => p.SelectToken("parentKey")) // Get the "parentKey" property in the current parent (if present)
.FirstOrDefault(k => k != null); // Return the first one found.
Console.WriteLine(parentKey);
Update
To get the name of the JSON property highest in the JSON container hierarchy, you would do:
var name = token.AncestorsAndSelf() // Walk up the list of ancestors
.OfType<JProperty>() // For each that is a property
.Select(p => p.Name) // Select the name
.LastOrDefault(); // And return the last (topmost).
Update 2
If you're looking for the first property name that appears in a JSON file, you can do the following, using JContainer.DescendantsAndSelf():
var json = #"[{""parentKey"":
{
""Name"": ""Name"",
""Id"": ""123"",
""Other"": null,
""nestedArr"":
[
""idx0"",
""idx1"",
""idx2""
]
}
}]";
var root = (JContainer)JToken.Parse(json);
var name = root.DescendantsAndSelf() // Loop through tokens in or under the root container, in document order.
.OfType<JProperty>() // For those which are properties
.Select(p => p.Name) // Select the name
.FirstOrDefault(); // And take the first.
Debug.WriteLine(name); // Prints "parentKey"
(JContainer represents a JSON node that can contain child nodes, such as an object or array.)

dynamic object handle problem Facebook C# sdk

I'm using Facebook C# sdk for desktop app. I'm getting the dynamic object and then extracting the name,id etc
dynamic result = fb.Get("/me");
string name=result.name;
Now problem is I can't extract the work information or favorite teams etc. I've used the required permissions, but unable to handle the dynamic object. It's in this format:
"languages": [
{
"id": "106502622718539",
"name": "Bānglā"
},
{
"id": "106059522759137",
"name": "English"
}
],
http://developers.facebook.com/tools/explorer/
Tried and searched a lot to get them. Found nothing. I've read that it comes in the form of array. Please help to extract those information through C# code..........
It looks like you might want:
dynamic result = fb.Get("/me");
foreach (dynamic language in result.languages)
{
Console.WriteLine("{0}: {1}", language.name, language.id);
}
Can't say I've used the Facebook SDK myself though.
Here is a golden rule on how to consume json data in Facebook C# SDK/SimleJson (internally Facebook C# SDK uses SimpleJson for json serializing/deserializing http://simplejson.codeplex.com/).
There are 3 possible types: Array, Json Object and privimitive types.
Array: Can be casted to IList<Object> or IList<dynamic>
JsonObject: key value pair - IDictionary<string, object>
primitive types: bool, string, long and double.
Since langauges is an array, you can use it as IList<object> and consume it in a for loop like mentioned by Json Skeet. You also get the benefit of other IList<T> features such as indexer and different properties of the array.
dynamic result = fb.Get("/me");
var langauges = result.languages;
var length = languages.Length;
var lang1 = languages[0];
var lang1Id = lang1["id"];
var lang1Name = lang1["name"];
var lang2 = langauges[1];
var lang2Id = lang2.id;
var lang2Name = lang2.name;
since lang1 and lang2 is a JsonObject you can either use indexer like lang1["id"] as you do in for IDictionary<string,object> or much easier use lang1.id.

Categories