I have been using json.NET successfully in projects for some time now without any problems. Last night I ran into my first case where json.NET crashed trying to parse json data returned from what should be a reliable source: the twitter API.
Specifically, this code causes the error:
string sCmdStr = String.Format("https://api.twitter.com/1/users/lookup.json?screen_name={0}", sParam);
string strJson = _oauth.APIWebRequest("GET", sCmdStr, null);
JObject jsonDat = JObject.Parse(strJson);
In my case the sParam string contained about 25 twitter numeric Ids. The twitter API call succeeded, but the json.NET Parse call failed with the following error:
"Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray"
Has anyone else run into this? Does anyone know any way around it? I am at a dead stop until I solve it.
I was getting the exact same error and eventually figured it out. Instead of using JObject.Parse use JArray.Parse. So here is your code:
string sCmdStr = String.Format("https://api.twitter.com/1/users/lookup.json?screen_name={0}", sParam);
string strJson = _oauth.APIWebRequest("GET", sCmdStr, null);
JArray jsonDat = JArray.Parse(strJson);
You can then loop through the array and create a jobject for each individual tweet.
for(int x = 0; x < jsonDat.Count(); x++)
{
JObject tweet = JObject.Parse(jsonDat[x].toString());
string tweettext = tweet["text"].toString();
//whatever else you want to look up
}
Related
I am trying to parse a JSON array by using this code:
public async Task QuoteAsync()
{
await this.Context.Channel.TriggerTypingAsync();
var client = new HttpClient();
var result = await client.GetStringAsync("https://zenquotes.io/api/random");
JArray qarray = JArray.Parse(result);
JObject quote = JObject.Parse(qarray[0]["q"].ToString());
JObject author = JObject.Parse(qarray[0]["a"].ToString());
await this.ReplyAsync($"{quote} - {author}");
}
The response I receive upon sending a request to zenquotes api is
[
{
"q": "Be where your enemy is not.",
"a": "Sun Tzu",
"h": "<blockquote>“Be where your enemy is not.” — <footer>Sun Tzu</footer></blockquote>"
}
]
I can't seem to figure out why the error is occurring since I don't really see any issues.
This is the error I am getting:
Unexpected character encountered while parsing value: A. Path '', line 0, position 0.
The error is occurring on the 7th line:
JObject quote = JObject.Parse(qarray[0]["q"].ToString());
and since the 8th line is the same I expect the same error.
According to JObject.Parse,
Load a JObject from a string that contains JSON.
For your "q" and "a", it is just a simple string but not a JSON string. Hence you should not use JObject.Parse.
With .ToString(), it is good enough to retrieve the value of q and a.
string quote = qarray[0]["q"].ToString();
string author = qarray[0]["a"].ToString();
Sample program
Hi I have an applicationn which i need to execute from run command:
D:\MyApplication.exe {\"mydllpath\":\"D:\\dll\",\"FilePath\":\"D:\\Input\\abc.doc\", \"Attribute\":\"word\"}
However, I am unable to extract the values in "mydllpath", "FilePath" and "Attribute", It shows errors while parsing.
error: Unexpected end of content while loading JObject. Path 'mydllpath', line 3, position 0.
code:
foreach (string arg in args)
{
var x = JObject.Parse(arg);
Any help would really be appreciated!
If escaping the JSON then you need to enclose it in a string
D:\MyApplication.exe "{\"mydllpath\":\"D:\dll\",\"FilePath\":\"D:\Input\abc.doc\", \"Attribute\":\"word\"}"
which will be received in the code as
{"mydllpath":"D:\dll", "FilePath":"D:\Input\abc.doc", "Attribute":"word"}
and allow for proper parsing.
var json = args[0];
var x = JObject.Parse(json);
I am connecting to an external API, that (given the parameters), prints a result set in JSON. The objective is to convert this JSON into readable values and add them to an object array. It's a UWP app, so some of the older libraries that I found on the internet were not available any more. The following is the code block that fetches the JSON and then attempts to parse it:
private void beginWork()
{
string feed_data = getFeed().Replace(#"\", "").Trim(new char[1] { '"' });
Debug.WriteLine(feed_data); // <-- THIS PRINTS OUT THE CORRECTLY FORMATTED JSON WITHOUT ANY ESCAPE CHARACTERS
JsonObject obj = JsonObject.Parse(feed_data); // <-- THROWS AN "INVALID JSON ERROR HERE" AND VALUE OF VARIABLE IN AUTOS SHOWS JSON DATA WITH ESCAPE CHARACTERS AND ADDITIONAL QUOTATION MARKS BEFORE AND AFTER THE STRING
}
private string getFeed()
{
HttpClient client = new HttpClient();
string url = "URL HERE";
HttpResponseMessage response = client.GetAsync(url).Result;
return response.Content.ReadAsStringAsync().Result;
}
So what's going wrong here? When the Debug.WriteLine(feed_data); line executed, I see valid JSON in the output console, but still get the parse error.
Edit: Sample JSON (expected and the one that shows in console):
[{"id":"884","author":"795","title":"The sum of ages of 5 children born at the intervals of 3 years each is 50 years. What is the age of the youngest child?","details":" ","datetime":"1439099443","answered":"1","vote":"0","answers":[{"id":"884","author":"788","answer":"4 years","datetime":"1439165670","votes":"0"}]}]
vs the JSON in Autos window and what the parsing fails on:
"[{\"id\":\"884\",\"author\":\"795\",\"title\":\"The sum of ages of 5 children born at the intervals of 3 years each is 50 years. What is the age of the youngest child?\",\"details\":\" \",\"datetime\":\"1439099443\",\"answered\":\"1\",\"vote\":\"0\",\"answers\":[{\"id\":\"884\",\"author\":\"788\",\"answer\":\"4 years\",\"datetime\":\"1439165670\",\"votes\":\"0\"}]}]"
Your JSON string represents JSON array instead of a JSON object. Using JSON.NET (I don't have the dev environment to test in UWP) I got the same error by doing JObject.Parse(feed_data), and it can be fixed by using JArray.Parse(feed_data). So, I strongly suspect that in UWP, the equivalent solution would be using JsonArray.Parse() :
JsonArray arr = JsonArray.Parse(feed_data);
I have gotten a Json string to parse before that was an array of objects much longer than just a simple string, which makes me think that I'm doing something wrong with the formatting.
Here is word for word what our webservice is outputting as the json string:
{"news":"What is Legal/Awesome Dre"}
the first part is simply what I named the string in the application (news) and the second part is the string that will be changing as the song does which is why I would like to pull in a simple string of it.
When I run the app I'm getting a parse error at these lines:
Console.Out.Writeline (content);
news = JsonConvert.DeserializeObject(content);
The application output will show the Json string as it is on the website, but I get an error right after that's telling me Invalid Token: startPath... which last time meant that my Json string was formatted wrong for how I need to grab the data.
Anyone can help me with this?
(P.S. I am working in Xamarin Studio (mono for android) using C#, if that makes any difference)
The problem is that your serialized JSON object isn't a string, it's an object with the string value you want at the "news" property/key/name. This is a simple way to get the string:
dynamic jsonObj = JsonConvert.DeserializeObject(content);
string news = jsonObj.news;
Or you can use an anonymous type:
var jsonObj = JsonConvert.DeserializeAnonymousType(content, new { news = "" });
string news = jsonObj.news;
Or create a type with a string News property:
MyNewsType jsonObj = JsonConvert.DeserializeObject<MyNewsType>(content);
string news = jsonObj.News;
These all work in the following way:
var content = #"{""news"":""What is Legal/Awesome Dre""}";
// above code
Console.WriteLine(news); // prints "What is Legal/Awesome Dre"
Try to put square bracket in your JSON:
[{"news":"What is Legal/Awesome Dre"}]
so I'm fairly new to programming but am looking to go much deeper with it. I recently started to get involved in a project to create a WinForm program for a website that uses an API system in JSON.
I've never used an API before so I'm not quite sure how it works but after looking at it for a few minutes I seem to have the gist of it. What I don't get is how exactly parsing JSON in C# works.
I found
this link after a little google searching. And I got it working (somewhat) with this code.
static void Main(string[] args)
{
WebClient c = new WebClient();
var vLogin = c.DownloadString("https://www.openraid.us/index.php/api/login/username/password");
//Returns string
//{"status":1,"error":null,"token":"250-1336515541-c48d354d96e06d488d1a2530071ef07c9532da26"}
//Token = random, no decisive length*/
JObject o = JObject.Parse(vLogin);
Console.WriteLine("Login Status: " + o["status"]);
String sToken = "" + o["token"];
Console.WriteLine(sToken);
Console.WriteLine("");
//Breaks after this
var myRaids = c.DownloadString("https://www.openraid.us/index.php/api/myraids/"+sToken);
JObject r = JObject.Parse(myRaids); //error occurs here
String sEventId = "" + r["event_id"];
Console.WriteLine("Event ID: " + sEventId);
Console.ReadLine();
}
So to me it looks like I have parsing 1 page done and handled, but when I move onto the second I get this error.
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
So I guess my question is, how do I parse more than 1 page or call of JSON and what would be the easiest way to break up each section of the JSON object (Such as status, error, and token, into C# strings?
Did you try to JArray instead? Depending on what kind of object you are trying to return
WebClient client = new WebClient();
var data = client.DownloadString("");
var jArray = JArray.Parse(data);
JSON requires brackets for arrays and commas between multiple objects.
This is per the JSON standard. I also recommend using JSON.net via NuGet instead of the native JSON parser unless it is overkill and you cannot have the extra bloat.
For example, your parsing a file with two seperate JSON objects - the following does not work per the JSON standard (lacks a comma between the 2 objects and the two objects are not encapsulated by brackets):
{"status":1,"error":null}
{"status":2,"error":null}
The following 3 JSON objects parsed from a file does work (has brackets for multiple objects and commas between objects):
[{"glossary": {"title": "fun glossary","SeeAlso": ["GML", "XML"]},
{"glossary": {"title": "grey glossary","SeeAlso": ["GML", "XML"]},
{"glossary": {"title": "blue glossary","SeeAlso": ["GML", "XML"]}]
You can cut every JSON object(Array) into more object using for loops
the C# API is System.Json
var jsonArray = JsonArray.Parse(st);//st is the string which contain the JSON objects
foreach (var item in jsonArray) {
JsonObject ob = new JsonObject(item);
foreach (var t in ob.Values) {
JsonObject oo = new JsonObject(t);
foreach (var x in oo) {
textBox1.AppendText(x.Key + “ : ” + x.Value + “\n”);
}
}
}