Decode Facebook MiniJson - c#

I am trying to extract the Picture url from the Json response from Facebook Api.
I get this result.Text
{"name":"John Wheeler",
"id":"1374317669554451",
"picture":{
"data":{
"is_silhouette":false,
"url":"https:\/\/fbcdn-profile-a.akamaihd.net\/hprofile-ak-xpf1\/v\/t1.0-1\/p50x50\/10930189_1374295206223364_7603927373095864161_n.jpg?oh=1f1a16fdd68dd9aa4ccc141d8ad38ed4&oe=55B344AC&__gda__=1437883587_e8970bb6ff145728e14118a180e5b40a"}}}
and this is the code to try to extract the info
//Deserializing JSON returned from server
Dictionary<string, object> JSON = Json.Deserialize(result.Text) as Dictionary<string, object>;
List<object> data = JSON["data"] as List<object>;
//Loop to traverse and process all the items returned from the server.
for (int i = 0; i < data.Count; i++)
{
string id = System.Convert.ToString(((Dictionary<string, object>)data[i])["id"]);
string name = System.Convert.ToString(((Dictionary<string, object>)data[i])["name"]);
Dictionary<string, object> picInfo = ((Dictionary<string, object>)data[i])["picture"] as Dictionary<string, object>;
string url = Util.DeserializePictureURLObject(picInfo);
}
I get an error KeyNotFoundException: The given key was not present in the dictionary.
John

Your code doesn't match the JSON shown. Your code assumes that there is a top-level property "data" that refers to an array, however this is not the case. Your JSON contains no arrays, merely a chain of properties picture -> data -> url, like so:
{
"name":"John Wheeler",
"id":"1374317669554451",
"picture":{
"data":{
"is_silhouette":false,
"url":"https:\/\/fbcdn-profile-a.akamaihd.net\/hprofile-ak-xpf1\/v\/t1.0-1\/p50x50\/10930189_1374295206223364_7603927373095864161_n.jpg?oh=1f1a16fdd68dd9aa4ccc141d8ad38ed4&oe=55B344AC&__gda__=1437883587_e8970bb6ff145728e14118a180e5b40a"
}
}
}
Thus, to extract this information, you must do:
var url = obj.ToDict()["picture"].DeserializePictureURLObject();
var name = System.Convert.ToString(obj.ToDict()["name"]);
var id = System.Convert.ToString(obj.ToDict()["id"]);
Using the extension methods:
public static class Util
{
public static IDictionary<string, object> ToDict(this object jsonObject)
{
return (IDictionary<string, object>)jsonObject;
}
public static string DeserializePictureURLObject(this object pictureObj)
{
// Adapted from http://answers.unity3d.com/questions/921336/found-my-highscore-on-facebook.html?sort=oldest
var picture = pictureObj.ToDict()["data"].ToDict();
object urlH = null;
if (picture.TryGetValue("url", out urlH))
{
return (string)urlH;
}
return null;
}
}
Your parsing code would work for JSON that looks like this:
{
"data":[
{
"name":"John Wheeler",
"id":"1374317669554451",
"picture":{
"data":{
"is_silhouette":false,
"url":"https:\/\/fbcdn-profile-a.akamaihd.net\/hprofile-ak-xpf1\/v\/t1.0-1\/p50x50\/10930189_1374295206223364_7603927373095864161_n.jpg?oh=1f1a16fdd68dd9aa4ccc141d8ad38ed4&oe=55B344AC&__gda__=1437883587_e8970bb6ff145728e14118a180e5b40a"
}
}
}
]
}

Related

How do I parse a JProperty to retreive nested values with variable keys

Given I have a JObject:
{
"results": {
"payroll_report": {
"314568": {
"user_id": 314568,
"client_id": "484781",
"start_date": "2020-03-29",
"end_date": "2020-04-04",
"total_re_seconds": 49260,
"total_pto_seconds": 94716,
"total_work_seconds": 143976,
"total_paid_break_seconds": 0,
"total_unpaid_break_seconds": 0,
"pto_seconds": {
"22322828": 57348,
"12597955": 37368
},
"total_ot_seconds": 0,
"total_dt_seconds": 0,
"timesheet_count": 16
}
}
},
}
How do I parse it so I can know the number of pto_seconds for 22322828?
I am already able to get total_pro_seconds and other elements at that level, but I can't figure out how to get the nested values.
My assumption is you want to access all the nested Key-Value pairs under the pto_seconds element and assume that json structure is always as it was given on the example.
Here is the full code to iterate over the list and get values. My second assumption is values are long type, that is why I used jToken.First().Value<long>(). If it is decimal or other types you can change it accordingly.
var jObject = JsonConvert.DeserializeObject<JObject>(json);
var jTokenList = jObject["results"]["payroll_report"]["314568"]["pto_seconds"].Children().ToList();
foreach (var jToken in jTokenList)
{
var ptoSecondKey = (jToken as JProperty).Name;
var ptoSecondValue = jToken.First().Value<long>();
}
Alternative method(without using JObject):
You can have real object representation of your JSON structure and you can use DeserializeObject<T> method to parse and return results as your object.
Here below you can find classes for your JSON:
public class ResultsMain
{
[JsonProperty("results")]
public ResultsDetail Results { get; set; }
}
public class ResultsDetail
{
[JsonProperty("payroll_report")]
public PayrollReport PayrollReport { get; set; }
}
public class PayrollReport
{
[JsonProperty("314568")]
public PayrollReportDetail Detail { get; set; }
}
public class PayrollReportDetail
{
[JsonProperty("pto_seconds")]
public Dictionary<string, long> PtoSeconds { get; set; }
}
To deserialize the JSON to your .NET type, you need below one line of code:
var resultsMain = JsonConvert.DeserializeObject<ResultsMain>(json);
Here is a snapshot of resultMain object:
You can enumerate over JObject, (if your initial JObject is named jObject)
var toEnumerate = (JObject)(jObject["results"]["payroll_report"]["314568"]["pto_seconds"]);
foreach(var pair in toEnumerate)
{
Console.WriteLine("Key: " + pair.Key);
Console.WriteLine("Value: " + pair.Value);
}
output:
Key: 22322828
Value: 57348
Key: 12597955
Value: 37368
I don't see any issue. See below 2 options are
static void Main(string[] args)
{
string json = File.ReadAllText("json1.json");
JObject jObject = JObject.Parse(json);
var results = jObject["results"];
var payroll_report = results["payroll_report"];
var user314568 = payroll_report["314568"];
var total_pto_seconds = user314568["total_pto_seconds"];
var pto_seconds = user314568["pto_seconds"];
///**************option1***********************
var val1 = pto_seconds["22322828"];
var val2 = pto_seconds["12597955"];
Console.WriteLine($"22322828: {val1}");
Console.WriteLine($"22322828: {val2}");
///**************option2***********************
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(pto_seconds.ToString());
foreach (var item in dict)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
Console.ReadLine();
}

Parse JSON array in c# to read array collection inside json

I have a below Jason format in which the Claims will be a array collection now I need to read all the Claims(which is a collection in below json) related to the policyid from c# , could anyone help me resoling it
{
"ClaimList": [{
"Claims": ["CL8901"],
"PolicyID": "W1234sd",
"ClaimsCount": 1
}, {
"Claims": ["CL3456", "CL1234"],
"PolicyID": "T1234sd",
"ClaimsCount": 2
}, {
"Claims": ["CL1321"],
"PolicyID": "C1234sd",
"ClaimsCount": 1
}]
}
string json = Util.ReadLine<string>();
JObject.Parse(json).SelectToken("ClaimList").Select(cl => new
{
PolicyId = cl.SelectToken("PolicyID"),
Claims = cl.SelectToken("Claims").ToObject<List<string>>()
}).Dump();
Linqpad code
http://share.linqpad.net/vqoav5.linq
To achieve what you need, do the following:
Follow my answer here to create C# classes for your json
Use NewtonSoft NuGet library to deserialize the JSON to C# objects
Perform whatever processing you need on the deserialized items
Here is some code once you have done the above:
var claims = JsonConvert.DeserializeObject<Rootobject>("YourJsonHere");
IEnumerable<Claimlist> claimsForPolicy=
claims.ClaimList.Where(x => x.PolicyID == "whateverYouNeed");
If you can use the Json.NET library (NuGet), this is pretty straightforward. First make sure you have a Claim class that has the structure of those inner objects in your JSON:
class Claim
{
public List<string> Claims { get; set; }
public string PolicyID { get; set; }
public int ClaimsCount { get; set; }
}
Having that class available, you can use Json.NET to do something like this:
using Newtonsoft.Json;
// ...
string yourJson = getYourJsonStringSomehow();
var claimsDict =
JsonConvert.DeserializeObject<Dictionary<string, List<Claim>>>(yourJson);
That will produce a Dictionary with one key: "ClaimsList", and the value will be a List of your Claim objects:
var claimsList = claimsDict["ClaimsList"];
var firstClaim = claimsList[0];
Console.WriteLine(firstClaim.PolicyID);
// Should print W1234sd
You can try this, first lets create a Json class for your json data:
public class JsonDoc
{
//I am adding an index on constructor for looping purposes
public JsonDoc(string json, int index)
{
JObject jObject = JObject.Parse(json);
JToken jResult = jObject["ClaimList"];
Claims = jResult[index]["Claims"].ToObject<string[]>();
}
//This constructor will return the number of count under ClaimList node
public JsonDoc(string json)
{
JObject jObject = JObject.Parse(json);
JToken jResult = jObject["ClaimList"][0];
intCount = jResult.Count();
}
private string[] Claims { get; set; }
public int intCount { get; set; }
}
Then to use this class for your Json data, first add a reference of Newtonsoft Json.
using Newtonsoft.Json.Linq;
Then on your sample data, I read all the data via file using StreamReader, loop on it and put all the data under a List:
private static void Main(string[] args)
{
using (StreamReader sr = new StreamReader(#"C:\Folder\myjson.json"))
{
string json = sr.ReadToEnd();
JsonDoc jSon = new JsonDoc(json);
//This will get the length of the array under ClaimList node
int intCount = jSon.intCount;
List<JsonDoc> lstResult = new List<JsonDoc>();
for (int x = 0; x < intCount; x++)
{
lstResult.Add(new JsonDoc(json, x));
}
}
}
The result is a List of JsonDoc class with array of string as part of property. This array of string is the result on your Claims Node. This JsonDoc class contains property Claims which is a string array which contains your Claims node:

How to create response from dictionary?

I am trying to create below response from dictionary:
['Employee1'] : List of skills
Code :
public class Skills
{
public string Skill {get;set;}
}
var skills=FetchSkills();
var dictionary = new Dictionary<string, List<Skills>>();
dictionary.Add('Employee1',skills);
Now i am trying to create below response:
'Employee1' =
{
{"skill":"skill1"},{"skill":"skill2"},{"skill":"skill3"}
}
I want skill property in camel case in my final response.
This is how i am trying to create response but not getting how to create expected response:
return Json(dictionary.Select
(
), JsonRequestBehavior.AllowGet);
Given class
public class Skills {
[JsonProperty("skill")]
public string Skill {get;set;}
}
and used like this
var skills=FetchSkills();
var dictionary = new Dictionary<string, List<Skills>>();
dictionary.Add('Employee1',skills);
return Json(dictionary, JsonRequestBehavior.AllowGet);
should produce
{
"Employee1":[
{"skill":"skill1"},{"skill":"skill2"},{"skill":"skill3"}
]
}

C# Deserialize JSON Response

I've written a csharp app which queries our load balancers (which are setup in an active/passive configuration) to determine which is the active. The load balancers have a REST API which I'm querying as such:
public void GetActiveLB()
{
// Create a new RestClient and RestRequest
var client = new RestClient("https://myloadbalancer.domain.local");
var request = new RestRequest("mgmt/tm/cm/failover-status", Method.GET);
// Specify authentication
client.Authenticator = new HttpBasicAuthenticator("myusername", "supersecret");
// ask for the response to be in JSON syntax
request.RequestFormat = DataFormat.Json;
//send the request to the web service and store the response when it comes back
var queryResult = client.Execute(request);
// Create a new Deserializer to be able to parse the JSON object
RestSharp.Deserializers.JsonDeserializer deserial = new JsonDeserializer();
var JSONObj = deserial.Deserialize<Dictionary<string, string>>(queryResult);
string lbstatus = JSONObj["description"];
}
The JSON returned to me looks like this:
{
"kind":"tm:cm:failover-status:failover-statusstats",
"selfLink":"https://localhost/mgmt/tm/cm/failover-status?ver=11.6.0",
"entries": {
"https://localhost/mgmt/tm/cm/failover-status/0": {
"nestedStats": {
"entries": {
"color": {
"description": "green"
},
"https://localhost/mgmt/tm/cm/failoverStatus/0/details": {
"nestedStats": {
"entries": {
"https://localhost/mgmt/tm/cm/failoverStatus/0/details/0": {
"nestedStats": {
"entries": {
"details": {
"description": "active for /Common/traffic-group-1"
}
}
}
}
}
}
},
"status": {
"description": "ACTIVE"
},
"summary": {
"description": "1/1 active"
}
}
}
}
}}
Here's a prettier formatted version:)
The path to the item I want is:
[JSON].entries.https://localhost/mgmt/tm/cm/failover-status/0.nestedStats.entries.status.description
What I am struggling with is how to get the value of this item particularly because it seems to be nested multiple times. Is there a way to provide an absolute path?
Thank You
Brad
If the json is always structured the same way you can create some poco's that nest themselves and then deserialise with the json deserialisation:
eg:
[DataContract]
public class JsonResponse
{
[datamember]
public string kind;
[datamember]
public string selflink;
[datamember]
public Entry entries; //we nest another object here just as in the json
}
[DataContract]
public class Entry
{
[datamember]
public nestedstat nestedstats;
}
(this is just loosly typed)
then:
JsonResponse response = new JavaScriptSerializer().Deserialize<JsonResponse>(jsonasstring);
The easiest way to do it is to use the dynamic keyword like this:
dynamic JSONObj =
deserial
.Deserialize<Dictionary<string, object>>(queryResult); //Notice how I am using Dictionary<string, object> instead of Dictionary<string, string> since some of the values are actually parents of other values so they will be presented as dictionaries themselves.
var lbstatus =
JSONObj
["entries"]
["https://localhost/mgmt/tm/cm/failover-status/0"]
["nestedStats"]
["entries"]
["status"]
["description"];
If you don't use the dynamic keyword then you would have to cast JSONObj["entries"] into a Dictionary<string,object>, and then when you access ["https://localhost/mgmt/tm/cm/failover-status/0"] on that dictionary, you would need to cast the result again into Dictionary<string,object> ... etc.
In this case, the dynamic keyword will make it very much easier.
If you want to get the result from an absolute path, you can do something like this with dynamic:
dynamic JSONObj = deserial.Deserialize<Dictionary<string, object>>(queryResult);
string path =
"entries.https://localhost/mgmt/tm/cm/failover-status/0.nestedStats.entries.status.description";
dynamic value = JSONObj;
foreach (var sub_path in path.Split('.'))
{
value = value[sub_path];
}
var lbstatus = value.ToString();

JSON array is not created properly for my scenario in json.net

I want to create a json string using json.net in C#. But the json array is not created as I expected. Here is my code:
markInfo[] MarkUpdate1=new markInfo[2];
string jsonString = JsonConvert.SerializeObject(new { MarkUpdate =MarkUpdate1 }, Formatting.Indented);
return jsonString;
public class markInfo
{
List<string> FinalMarks = new List<string>();
List<string> EvalMarks = new List<string>();
}
My expected output is :
{
"MarkUpdate":[
{
"FinalMarks":[
{
}
]
},
{
"EvalMarks":[
{
}
]
}
]
}
But it generated the following output :
{
"MarkUpdate": [
null,
null
]
}
You're creating an anonymous type which has a MarkUpdate property which is assigned the value of your array which contains no object instances.
Are you trying to output one instance of a MarkUpdate? in which case remove your array, instantiate your markInfo class and serialize that.
You should also make your FinalMarks and EvalMarks properties, they are also not marked as public.
string jsonString =
JsonConvert.SerializeObject(new MarkInfo(), Formatting.Indented);
return jsonString;
public class MarkInfo
{
private List<string> finalMarks;
private List<string> evalMarks;
public List<string> FinalMarks
{
get { return this.finalMarks ?? (this.finalMarks = new List<string>()); }
set { this.finalMarks = value; }
}
public List<string> EvalMarks
{
get { return this.evalMarks ?? (this.evalMarks = new List<string>()); }
set { this.evalMarks = value; }
}
}
This line:
markInfo[] MarkUpdate1=new markInfo[2];
...creates an array of markInfo but doesn't create the instances; both of the array slots are empty. So at the least you need to create them:
markInfo[] MarkUpdate1=new markInfo[2];
markInfo[0] = new markInfo();
markInfo[1] = new markInfo();
That still won't give you your "expected output", though, because your expected output only has a single entry, but your code is defining two entries.

Categories