C# and jSON is not working - c#

Need a little help here
So I have a json url and need to get each item into a for each loop
Here is the json
{
"_links": { },
"count": 9,
"list": {
"staff": [
"staff1",
"staff2",
"staff3"
],
"clients": [
"client1",
"client2",
"client3",
"client4",
"client5",
"client6"
]
}
}
I have also got the following code in c# but keep getting errors
string source;
var sURL = "LINK_TO_JSON_URL";
WebRequest req = HttpWebRequest.Create(sURL);
req.Method = "GET";
req.Timeout = 5000;
try
{
using (StreamReader reader = new StreamReader(req.GetResponse().GetResponseStream()))
{
source = reader.ReadToEnd();
reader.Close();
}
JToken jObject = JObject.Parse(source);
string clients = (string)jObject["list"]["clients"];
//for each loop here
}
catch (Exception ex)
{
//error message here
}
What is it that I am doing wrong? I have tried to convert string to array and still get nothing.
I want to be able to get each clients names
Cheers

So here is some code to show iterating over a JArray that contains strings. This code has been tested with your json and outputs each client string.
var jObject = JObject.Parse(source);
foreach (var client in jObject["list"]["clients"])
{
Console.WriteLine((string)client);
}

Look at this piece of code
#region Model For Deserialize String to Object
public class Links
{
}
public class List
{
public List<string> staff { get; set; }
public List<string> clients { get; set; }
}
public class RootObject
{
public Links _links { get; set; }
public int count { get; set; }
public List list { get; set; }
}
#endregion
#region Restfull Respone (String) Convert To RootObject
public class ConvertStringToObj
{
public void Execute()
{
//Your webReq and Response progress here
string jsonResponse="";
var rootObj = (RootObject)Newtonsoft.Json.JsonConvert.DeserializeObject(jsonResponse, typeof(RootObject));
foreach(var eachItem in rootObj.list.staff)
{
var stafName = eachItem;
}
}
}
#endregion
Here is an solution, you can do this via Objects :)

Related

Extract properties from Newtonsoft jObject

I have a .net core console application where I am trying to get the values of two properties that are within a returned JSON object. I have highlighted where the error is on line 43, can someone please show me where I am going wrong thank you!
Error:
System.ArgumentException: Accessed JArray values with invalid key value: "name". Int32 array index expected.
at Newtonsoft.Json.Linq.JArray.get_Item(Object key)
at PBXApp.Program.GetUser() in C:\Development\PBXApp\PBXApp\Program.cs:line 43
Returned JSON:
{
"results":[
{
"name":"bulbasaur",
"url":"https://pokeapi.co/api/v2/pokemon/1/"
},
{
"name":"ivysaur",
"url":"https://pokeapi.co/api/v2/pokemon/2/"
},
{
"name":"venusaur",
"url":"https://pokeapi.co/api/v2/pokemon/3/"
}
]
}
Program.cs -
// retrieve asynchronous data from remote api
public static async Task GetUser()
{
//baseUrl
string baseUrl = "http://pokeapi.co/api/v2/pokemon/";
try
{
// HttpClient implements a IDisposable interface
using (HttpClient client = new HttpClient())
{
//initiate Get Request (await will execute the using statement in order)
using (HttpResponseMessage res = await client.GetAsync(baseUrl))
{
//get content from response, then convert it to a c# object
using (HttpContent content = res.Content)
{
//assign content to data variable by converting into a string using await
var data = await content.ReadAsStringAsync();
//convert data using newtonsoft JObject Parse class method
if (data != null)
{
//parse data into an object.
var dataObj = JObject.Parse(data)["results"];
enter code here
//ERROR ON THIS LINE
UserItem userItem = new UserItem(name: $"{dataObj["name"]}", url: $"{dataObj["url"]}");
//log userItem name and url to console
Console.WriteLine("Name:{0} Url:{1}", userItem.Name, userItem.Url);
}
else
{
Console.WriteLine("No returned data");
}
}
}
}
}
//exceptions
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
UserItem.cs -
public class UserItem
{
public UserItem(string name, string url)
{
Name = name;
Url = url;
}
public string Name { get; set; }
public string Url { get; set; }
}
dataObj is a JSON array, but not with named keys. It is just a regular array. So you can't access it with a key named "name", because that key doesn't exist.
You could use a numeric index, but you don't know in advance (from the JObject) how long the array is. So it's better to parse it as an array, and loop over the items:
var dataObj = JArray.Parse(data)["results"];
foreach (var record in dataObj)
{
var name = record["name"];
// ...
}
But why go through all the hassle of manually parsing JSON? Just create classes to hold the results, and deserialize all at once:
public class Pokémon
{
public string name { get; set; }
public string url { get; set; }
}
public class ListOfPokémon
{
public List<Pokémon> results { get; set; }
}
var result = JsonConvert.DeserializeObject<ListOfPokémon>(jsonString);
foreach (var p in result.results)
{
// ...
}

Display JSON DATA in dataGridView

I want to display JSON data in DGview in c#
I tried 2 codes works with Newtonsoft.Json
but both of them shows error invalid input but input is correct as I know
this is an input
https://dastanito.ir/test/ex2/api/storiesmaster/read.php
{"StoriesMasters":[{"id":"4545","story_code":"xv35454","master_code":"mvm,454"},{"id":"2","story_code":"002a","master_code":"he3385_1"},{"id":"60","story_code":"001a","master_code":"he3385_1"},{"id":"3","story_code":"c57675","master_code":"ara3433_2"},{"id":"45","story_code":"hdgw878","master_code":"f998989d"},{"id":"50","story_code":"d8885","master_code":"za76787_3"}]}
this is the first code I used:
using Newtonsoft;
using Newtonsoft.Json;
using System.Net;
using Newtonsoft.Json.Linq;
void get_response()
{
WebClient wp = new WebClient();
string url = "http://dastanito.ir/test/ex2/api/storiesmaster/read.php";
var response=wp.DownloadString(url);
get_data(response);
}
void get_data(string response)
{
dataGridView1.Rows.Clear();
JArray fetch= JArray.Parse(response);
if(fetch.Count()>0)
{
for(int i=0;dataGridView1.Rows.Count>i;i++)
{
int n=dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value=fetch[i]["JsonObjectName1"].ToString();
}
}
}
and the other one is :
using RestSharp;
using Newtonsoft;
using Newtonsoft.Json;
using System.Net;
using Newtonsoft.Json.Linq;
public class JsonResult
{
public int id { get; set; }
public string story_code { get; set; }
public int master_code { get; set; }
}
void getdata()
{
var client = new RestClient("http://dastanito.ir");
var request = new RestRequest("test/ex2/api/storiesmaster/read.php", Method.GET);
// execute the request
IRestResponse response = client.Execute(request);
var content = response.Content;
richTextBox1.Text = response.Content;
var result = JsonConvert.DeserializeObject<List<JsonResult>(content);
dataGridView1.DataSource = result;
}
and the ERROR IS
ERROR
You need to create two classes as following.
public class Data
{
public int Id { get; set; }
public string story_code { get; set; }
public string master_code { get; set; }
}
public class DataList
{
public List<Data> StoriesMasters { get; set; }
}
now you can deserialize the json to an object of DataList class as following.
var result = JsonConvert.DeserializeObject<DataList>(content);
And now you can bind StoriesMasters property to grid view.
dataGridView1.DataSource = result.StoriesMasters;
Your json entry entity is object, not array. Array starts with [ ] and object starts with { } brackets.
Change JArray fetch = JArray.Parse(response); to JObject fetch = JObject.Parse(response);

.net json deserializer failing for google api returned json result

I am unable to deserialize the json result I am getting from google api during an API call. The API request is successful, but I can't deserialize it.
Code for deserialization is as follows :
var datareceived = JsonConvert.DeserializeObject<RootObject>(response);
Please find below the json I am getting from Google api(response object in above code) :
{"result":[]}
{"result":[{"alternative":[{"transcript":"distance between the trees","confidence":0.46962094},{"transcript":"Justin prescription that reason"},{"transcript":"Justin Swift accessories"},{"transcript":"justice respiratory"},{"transcript":"Justin syska accessories"}],"final":true}],"result_index":0}
Exception Details :
Message = "Additional text encountered after finished reading JSON content: {. Path '', line 2, position 0."
RootObject Class :
public class RootObject
{
public List<Result> result { get; set; }
public int result_index { get; set; }
}
Any help would be highly appreciated!
you just can't parse this JSON as it is because } symbolize the end of JSON
but you can do something like this
string json = "{\"result\":[]}\r\n{\"result\":[{\"alternative\":[{\"transcript\":\"distance between the trees\",\"confidence\":0.46962094},{\"transcript\":\"Justin prescription that reason\"},{\"transcript\":\"Justin Swift accessories\"},{\"transcript\":\"justice respiratory\"},{\"transcript\":\"Justin syska accessories\"}],\"final\":true}],\"result_index\":0}";
string trueJson = json.Split(new[] { Environment.NewLine }, StringSplitOptions.None)[1];
try
{
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(trueJson);
rootObject = rootObject;
}
catch (Exception ex)
{
throw;
}
public class Alternative
{
public string transcript { get; set; }
public double confidence { get; set; }
}
public class Result
{
public List<Alternative> alternative { get; set; }
public bool final { get; set; }
}
public class RootObject
{
public List<Result> result { get; set; }
public int result_index { get; set; }
}
You can utilize following method to get JSON in List:
public List<string> GetJsonItems(string jsonString)
{
int bracketCount = 0;
List<string> jsonItems = new List<string>();
StringBuilder Json = new StringBuilder();
foreach (char c in jsonString)
{
if (c == '{')
++bracketCount;
else if (c == '}')
--bracketCount;
Json.Append(c);
if (bracketCount == 0 && c != ' ')
{
jsonItems.Add(Json.ToString());
Json = new StringBuilder();
}
}
return jsonItems;
}
Then utilize it like:
List<string> strings = GetJsonItems(response.Replace(Environment.NewLine, String.Empty));
if (strings.Length > 1)
{
List<Rootobject> allResultSet = new List<Rootobject>();
foreach (var str in strings)
{
Rootobject items = JsonConvert.DeserializeObject<Rootobject>(str);
if (items.result.Length > 0)
{
allResultSet.Add(items);
}
}
}
It seems that each line of the result contains a separate JSON object. (It's not clear why the API doesn't return an actual JSON array instead.) If this is the case, you can split the response into lines and parse each line separately:
string[] lines = response.Split(new char[]{'\r','\n'},StringSplitOptions.RemoveEmptyEntries);
var datareceived1 = JsonConvert.DeserializeObject<RootObject>(lines[0]);
... and so on.

JSON Not Deserializing

This is one of my first ventures into WCF/JSON. I created a WCF Web Service. This is one of my methods. It is how I serialize the datable to JSON.
public string GetPrayers()
{
DataTable myDt = new DataTable();
myDt = sprocToDT("LoadPrayers");
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(myDt, Formatting.None);
return JSONString;
}
This returns a nice JSON Dataset:
{"GetPrayersResult":"[{\"prayerid\":2,\"prayer\":\"Please pray for my
dog Rusty. He has cancer
:(\",\"prayerCategory\":\"General\",\"prayerDate\":\"2017-06-10T21:24:16.1\",\"handle\":\"GuruJee\",\"country\":\"USA\"},{\"prayerid\":1,\"prayer\":\"Help
Me I need a appendectomy
STAT\",\"prayerCategory\":\"Sports\",\"prayerDate\":\"2017-04-10T20:30:39.77\",\"handle\":\"GuruJee\",\"country\":\"USA\"}]"}
When I go to deserialize it I get all nulls. Here is the classes I created:
public class PrayUpPrayers
{
public string prayer { get; set; }
public string prayerid { get; set; }
public string prayerCategory { get; set; }
public string prayerCategoryID { get; set; }
public string prayerDate { get; set; }
public string handle { get; set; }
public string country { get; set; }
}
public class ThePrayer
{
public PrayUpPrayers prayers { get; set; }
}
}
This is how I am retrieving the JSON:
void getData()
{
var request = HttpWebRequest.Create(string.Format(#"URLGoesHere"));
request.ContentType = "application/json";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var content = reader.ReadToEnd();
string foo = content.ToString();
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.PrayUpPrayers>(foo,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
Testing is always null? Is the issue that I am serializing it wrong, could it be the class structure, or is it related to how I am deserializing it. One important note: I checked my JSON on one of these JSONClassesFromC# sites and it only returns the GetPrayersResult as the only class item. Ignoring completely my entire structure.
You didn't provide the code for sprocToDT, but it should create ThePrayer object witch should contain list of PrayUpPrayers
public class ThePrayer
{
public List<PrayUpPrayers> prayers { get; set; }
}
And then you should deserialize ThePrayer object, not PrayUpPrayers.
For example
PrayUpPrayers prayUpPrayers1 = new PrayUpPrayers
{
prayer = "Please pray for my dog Rusty. He has cancer",
prayerid = "2",
prayerCategory = "General",
prayerDate = "2017-06-10T21:24:16.1",
handle = "GuruJee",
country = "USA"
};
PrayUpPrayers prayUpPrayers2 = new PrayUpPrayers
{
prayer = "Help Me I need a appendectomy STAT",
prayerid = "1",
prayerCategory = "Sports",
prayerDate = "2017-04-10T20:30:39.77",
handle = "GuruJee",
country = "USA"
};
ThePrayer thePrayer = new ThePrayer
{
prayers = new List<PrayUpPrayers>
{
prayUpPrayers1, prayUpPrayers2
}
};
myDt in your code should be the same as thePrayer instance in my code.
JSONString = JsonConvert.SerializeObject(myDt, Formatting.None);
will provide Json that looks like
"{\"prayers\":[{\"prayer\":\"Please pray for my dog Rusty. He has
cancer\",\"prayerid\":\"2\",\"prayerCategory\":\"General\",\"prayerCategoryID\":null,\"prayerDate\":\"2017-06-10T21:24:16.1\",\"handle\":\"GuruJee\",\"country\":\"USA\"},{\"prayer\":\"Help
Me I need a appendectomy
STAT\",\"prayerid\":\"1\",\"prayerCategory\":\"Sports\",\"prayerCategoryID\":null,\"prayerDate\":\"2017-04-10T20:30:39.77\",\"handle\":\"GuruJee\",\"country\":\"USA\"}]}"
And deserialize will look like
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.ThePrayer>(foo,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
that's simple. you should deserilze the output twice. try this:
var output= DeserializeObject<string>(foo);
var testing = JsonConvert.DeserializeObject<prayupapp.ModelClasses.PrayUpPrayers>(output,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});

Newtonsoft JSON deserialize using HttpWebResponse

I was searching in all the questions about deserialization with Newtonsfot Json Converter. But i wasn't able to find the problem in my code. So I put here, asking for help.
The message error from the visual studio:
No se controló Newtonsoft.Json.JsonSerializationException
HResult=-2146233088
Message=Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'APIEffilogics.Usuari+Client' because the type requires a
JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array.
JsonArrayAttribute can also be added to the type to force it to
deserialize from a JSON array.
My JSON response is like this:
[ {
"id": 32,
"consultancy_id": 1,
"nif": "B61053922",
"contactname": "",
"email": "",
"phone": "",
"active": true,
"description": "Keylab" },
{
"id": 19,
"consultancy_id": 1,
"nif": "P0818300F",
"contactname": "Pau Lloret",
"email": "lloret#citcea.upc.edu",
"phone": "",
"active": true,
"description": "Rubi" } ]
And those are the classes:
namespace APIEffilogics
{
public class Usuari
{
public string access_token; //Encapsulat que conté la identificació de seguretat
public string token_type; //Tipus de token, "Bearer"
public string response; //Resposta de l'API
public class Client : Usuari //Estructura client
{
[JsonProperty("id")]
public string cid { get; set; }
[JsonProperty("consultancy_id")]
public string consultancy_id { get; set; }
[JsonProperty("contactname")]
public string contactname { get; set; }
[JsonProperty("email")]
public string email { get; set; }
[JsonProperty("description")]
public string description { get; set; }
[JsonProperty("nif")]
public string nif { get; set; }
[JsonProperty("phone")]
public string phone { get; set; }
[JsonProperty("active")]
public string active { get; set; }
}
public class Building : Usuari //Estructura edifici
{
public string descrip;
public string bid;
}
public class Floor : Usuari //Estructura planta
{
public string descrip;
public string fid;
}
public class Room : Usuari //Estructura habitació
{
public string descrip;
public string rid;
}
public class Node : Usuari //Estructura nodes
{
public string[] descrip;
public string[] nid;
public string[] model;
public string[] type;
}
}
//************************END PUBLIC CLASS Usuari***************************//
}
The code that I use:
public void Request(string url, string metode)
{
try
{
//Enviem la petició a la URL especificada i configurem el tipus de connexió
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.KeepAlive = true;
myReq.Headers.Set("Cache-Control", "no-store");
myReq.Headers.Set("Pragma", "no-cache");
myReq.Headers.Set("Authorization", usuari.token_type + " " + usuari.access_token);
if (metode.Equals("GET") || metode.Equals("POST"))
{
myReq.Method = metode; // Set the Method property of the request to POST or GET.
if (body == true)
{
// add request body with chat search filters
List<paramet> p = new List<paramet>();
paramet p1 = new paramet();
p1.value = "1";
string jsonBody = JsonConvert.SerializeObject(p1);
var requestBody = Encoding.UTF8.GetBytes(jsonBody);
myReq.ContentLength = requestBody.Length;
myReq.ContentType = "application/json";
using (var stream = myReq.GetRequestStream())
{
stream.Write(requestBody, 0, requestBody.Length);
}
body = false;
}
}
else throw new Exception("Invalid Method Type");
//Obtenim la resposta del servidor
HttpWebResponse myResponse = (HttpWebResponse)myReq.GetResponse();
Stream rebut = myResponse.GetResponseStream();
StreamReader readStream = new StreamReader(rebut, Encoding.UTF8); // Pipes the stream to a higher level stream reader with the required encoding format.
string info = readStream.ReadToEnd();
var jsondata = JsonConvert.DeserializeObject<Usuari.Client>(info);
myResponse.Close();
readStream.Close();*/
}
catch (WebException ex)
{
// same as normal response, get error response
var errorResponse = (HttpWebResponse)ex.Response;
string errorResponseJson;
var statusCode = errorResponse.StatusCode;
var errorIdFromHeader = errorResponse.GetResponseHeader("Error-Id");
using (var responseStream = new StreamReader(errorResponse.GetResponseStream()))
{
errorResponseJson = responseStream.ReadToEnd();
}
}
}
I don't know where is the problem, the response have the correct JSON scheme. Somebody can explain me where is the problem in my code, or if I'm not doing correctly.
I've solved the problem how you say, nut now I've a similar problem and the same message error. The JSON response now is this:
{
nodes: [
{
id: 5,
global_id: 5,
description: "Oven",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 2,
nodetype_id: 1
},
{
id: 39,
global_id: 39,
description: "Fridge",
room_id: 2,
floor_id: 1,
building_id: 1,
client_id: 2,
nodemodel_id: 8,
nodetype_id: 1
}, ...
],
limit: 10,
offset: 0
}
And those are the classes:
public class Node : Usuari //Estructura nodes
{
[JsonProperty("limit")]
public int limit { get; set; }
[JsonProperty("offset")]
public int offset { get; set; }
[JsonProperty("nodes")]
public List<Node_sub> nodes_sub { get; set; }
}
public class Node_sub : Node
{
[JsonProperty("id")]
public string nid { get; set; }
[JsonProperty("global_id")]
public string gid { get; set; }
[JsonProperty("description")]
public string descrip { get; set; }
[JsonProperty("room_id")]
public string rid { get; set; }
[JsonProperty("floor_id")]
public string fid { get; set; }
[JsonProperty("client_id")]
public string cid { get; set; }
[JsonProperty("building_id")]
public string bid { get; set; }
[JsonProperty("nodemodel_id")]
public string model { get; set; }
[JsonProperty("nodetype_id")]
public string type { get; set; }
}
The code is the same as before, only I add this sentences:
jsonnode = JsonConvert.DeserializeObject<List<Usuari.Node>>(info);
Why I'm having the same error? List<Usuari.Node> is an array that contains all the items of JSON message.
Thanks
Try
var jsondata = JsonConvert.DeserializeObject<List<Usuari.Client>>(info);
This addresses the issue as the exception suggests:
To fix this error either change the JSON to a JSON object (e.g.
{"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array
Emphasis added to highlight the salient point
The HTTP response you receive is an array of objects so you need to deserialise it in a way that can deal with an array of objects. By changing your code to deserialise into a List<Usari.Client> you do just that and it should resolve the error.

Categories