I try to get parse JSON response for the following link:
https://graph.facebook.com/feed/?ids=135395949809348,149531474996&access_token=
The response is like that:
{
"135395949809348": {
"data": [
{
....Some data
}]
}
,
"325475509465": {
"data": [
{
....Some data......
}]
}
}
I use System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(string json) method.
But the objects key names always different , so I can't define the class that can be used for parsing this response.
Is anyone has any experience in parsing multiple id's response from Facebook?
With JSON.NET you can read the respose as JObject and then access it via indexer.
var json = JObject.Parse(result);
var array = json["325475509465"]["data"];
Then you can deserialize objects from array...
What is your issue with the Deserialize? Deserialize is going to produce a Dictionary, with potential inner arrays and dictionary instances too....
It wouldn't parse as a custom object unless you build a serializer to do that... or look at JSON.NET: http://james.newtonking.com/pages/json-net.aspx
Related
I have hard time deserializing the json response from Solr search engine.
I use Newtonsoft Json.NET.
Simplified response from Solr:
{
"suggestions": [
{
"someword": {
"numFound": 1
}
}
]
}
I deserialize this to a list of KeyValuePair<string, customobject>.
customobject test = Newtonsoft.Json.JsonConvert.DeserializeObject<customobject>(jsonText);
It worked, until a user typed the word "key", so Solr returned that JSON:
{
"suggestions": [
{
"key": {
"numFound": 1
}
}
]
}
The deserialization of this JSON raise this error :
Unexpected character encountered while parsing value
...
Ok. I just realized that even if it doesn't raise an exception with words other than "key", it doesn't work because the KeyValuePair in the output object are always empty.
I had never realized this problem before because this part of the Json (Spellcheck Suggestions) is never used.
So easy fix: we do not serialize suggestions anymore.
But, if anyone still want to answer the question, in what kind of object will you deserialize this Json (from Solr)?
{
"suggestions":
[
{"brack":{
"numFound":10,
"startOffset":0,
"endOffset":5,
"origFreq":0,
"suggestion":[{
"word":"back",
"freq":78},
{
"word":"black",
"freq":1}
]}},
{"key":{
"numFound":1,
"startOffset":6,
"endOffset":9,
"origFreq":12,
"suggestion":[{
"word":"key",
"freq":15}]}}]
}
I don't think a dictionary can do the job :
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,Test.SpellCheckSuggestion]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
As mentioned in a comment above, the solution is to use a list of dictionary. (not just a dictionary and not a list of KeyValuePair)
List<Dictionary<string, SpellCheckSuggestion>>
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.
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);
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.
I have a List that, when serialized as JSON gives me an array of objects. However, I need the serialized version to be structured as follows:
{
"item3":{
"id":3,
"name":"monkey"
},
"item4":{
"id":4,
"name":"turtle"
}
}
Currently, the JSON serialization is structured like this:
[
{
"id":3,
"name":"monkey"
},
{
"id":4,
"name":"turtle"
}
]
My goal is to be able to reference the array by item ID instead of numeric index (ie. arr["item3"].name instead of arr[0].name).
You might did that just putting the data into a dictionary is enough for JaveScripySerializer:
var dict = list.ToDictionary(
item => "item" + item.id);
(and serialize dict)
If not:
I don't have a PC handy for an example, but you should be able to:
write a wrapper class that encapsulated the list/array
use the JavaScriptSerializer class
after creating the serializer, associate the wrapper-type with a custom serializer
in the custom serializer, iterate over the data, adding a key to the dictionary per-item, i.e. data.Add("item"+i,list[i]);
You associate custom maps via RegisterConverters: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.registerconverters.aspx
Note you don't need to write a deserialize unless you need that too.
If you get stuck, I'll try to ad an example later.