So after doing a web request, I get this JSON string back:
{"status":"okay","result":[{"id":8810,"country":"IE","region":"07","city":"Dublin","latitude":53.3331,"longitude":-6.2489,"comment":"407367 donkeys"},{"id":9688,"country":"IE","region":"04","city":"Cork","latitude":51.8986,"longitude":-8.4958,"comment":"454765 donkeys"},{"id":9963,"country":"IE","region":"06","city":"Donegal","latitude":54.65,"longitude":-8.1167,"comment":"315518 donkeys"}]}
I'm not sure how to parse it. I have a City class that has id, country, region etc, and I would like to be able to save each one separately in a list so I can add them to a List View for an app.
I have tried this:
JObject jobj = JObject.Parse(jsonString);
JToken jstatus = jobj["status"];
JToken jresult = jobj["result"];
status = (String)jstatus;
JArray arrayOfCities = JArray.Parse(jsonString);
if (status.Equals("okay"))
{
foreach (JObject o in arrayOfCities.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
id = p.Name + p.Value.ToString();// (String)jresult["id"];
country = (String)jresult["country"];
region = (String)jresult["region"];
city = (String)jresult["city"];
latitude = (String)jresult["latitude"];
longitude = (String)jresult["longitude"];
comment = (String)jresult["comment"];
}
}
}
However I keep getting parse errors in it. I tried a few things, but none end up working.
How could I parse each part of the array separately and save it to a City List.
Thanks
You should use DeserializeObject. Here's an example:
public class CitiesResponse
{
public string Status { get; set; }
public List<City> Result { get; set; }
}
var response = JsonConvert.DeserializeObject<CitiesResponse>(jsonString);
// response.Result is your list of cities
Related
I'm new to JSON and looked at all the possible answers, but still not able to get it. Basically I'm getting the list of all users and storing it as string. Below is the result Json output string.
[{"Links":[],"RequestedObject":{"Id":181,"DisplayName":"User, Migration","FirstName":"Migration","MiddleName":null,"LastName":"User","LastLoginDate":"2008-01-10T11:04:00","UserName":"1564134","AccountStatus":2,"DomainId":null,"UpdateInformation":{"CreateDate":"2008-01-10T17:04:24.72","UpdateDate":"2011-10-07T16:35:51.74","CreateLogin":2,"UpdateLogin":2}},"IsSuccessful":true,"ValidationMessages":[]},{"Links":[],"RequestedObject":{"Id":16167,"DisplayName":"Xyz, Abc","FirstName":"Abc","MiddleName":null,"LastName":"Xyz","LastLoginDate":"2022-03-04T15:54:29.43","UserName":"1514834","AccountStatus":1,"DomainId":null,"UpdateInformation":{"CreateDate":"2022-03-04T15:53:14.817","UpdateDate":"2022-03-04T15:54:29.293","CreateLogin":14760,"UpdateLogin":11743}},"IsSuccessful":true,"ValidationMessages":[]}]
As you can see first part is JArray and then Jobject. My requirement is to get all "RequestedObject" that have "CreateDate" greater than or equal to CurrentDate. Is there a simple way to achieve this using linq instead of foreach loop. Here is code that I was able to put in from all other answers.
try
{
string text = System.IO.File.ReadAllText(#"H:\Test.txt");
DateTime previousRunTime = new DateTime(2022, 01, 31);
JArray jsonArray = JArray.Parse(text);
var jsonObjects = jsonArray.OfType<JObject>().ToList();
//var users1 = from item in jsonObjects.Children()["RequestedObject"].Value<string>()
// select item;
var abc = jsonObjects.Properties().Where(p => p.Name == "RequestedObject").Select(p => p.Value);
foreach(var q in abc)
{
Console.WriteLine(q.Value<string>("Id").ToString());
}
}
catch (Exception p)
{
Console.WriteLine(p.Message);
}
Looking for solution something like below
var users =
from item in jsonObjects["RequestedObject"]
where item["UpdateInformation"]["CreateDate"].Value<DateTime>() >= previousRunTime
select new UserDetails
{
UserName = item["UserName"].Value<string>(),
UserID = item["Id"].Value<string>(),
};
public class UserDetails
{
public string UserName { get; set; }
public string UserID { get; set; }
}
Thanks,
Prem
RequestedObject is a property on the objects in the array, not the array itself.
var users =
from item in jsonObjects
let obj = item["RequestedObject"]
where (DateTime)obj["UpdateInformation"]["CreateDate"] >= previousRunTime
select new UserDetails
{
UserName = (string)obj["UserName"],
UserID = (string)obj["Id"],
};
you need only one line code if you are using LINQ to JSON
List<UserDetails> users = jsonArray.Where(i => (DateTime)i["RequestedObject"]
["UpdateInformation"]["CreateDate"] >= previousRunTime)
.Select(i => i["RequestedObject"].ToObject<UserDetails>()).ToList();
class
public class UserDetails
{
[JsonProperty("UserName")]
public string UserName { get; set; }
[JsonProperty("Id")]
public string UserID { get; set; }
}
I have this JSON string called assignee:
{
"id": 15247055788906,
"gid": "15247055788906",
"name": "Bo Sundahl",
"resource_type": "user"
}
I want to get the "name" element and its value if it's not null. I have tried
var jobject = JsonConvert.DeserializeObject<JObject>(assignee);
And
var jo = JObject.Parse(assignee);
I tried looping through it but I just get null exception or empty output even though if I just print the assignee variable itself its filled with data.
My loop is like:
foreach (var result in jobject["name"])
{
Debug.WriteLine(result);
}
The simplest and best way is to deserialise to a C# class, for example:
public class Data
{
public long Id { get; set; }
public string Name { get; set; }
//etc..
}
And deserialise like this
var data = JsonConvert.DeserializeObject<Data>(json);
var name = data.Name;
To get name use this
string name = jobject["name"];
Using ["name"] returns a JToken, it is null if the property doesn't exist
JToken token = jo["name"];
Debug.WriteLine(token?.ToString() ?? "<default value>");
If you don't know properties beforehand, you can loop through JObject properties and get name value pairs as following:
var jsonObject = JObject.Parse(str);
foreach (var item in jsonObject)
{
var name = item.Key;
JToken token = item.Value;
if (token is JValue)
{
var value = token.Value<string>();
}
}
Here is how it should work:
class Data
{
public long? Id { get; set; }
public string Gid { get; set; }
public string Name { get; set; }
public string Resource_Type { get; set; }
}
class Program
{
static void Main(string[] args)
{
string assignee = "{\"id\": 15247055788906, \"gid\": \"15247055788906\", \"name\": \"Bo Sundahl\", \"resource_type\": \"user\"}";
Data data = JsonConvert.DeserializeObject<Data>(assignee);
Console.WriteLine(data.Id);
Console.WriteLine(data.Gid);
Console.WriteLine(data.Name);
Console.WriteLine(data.Resource_Type);
Console.ReadLine();
}
}
Is there any way to combine 2 foreach loops?
I'm trying to get the value of “total” and “Na” from a JSON file in one loop but I doesn’t work.
I can’t find the value of “total” when I use “data.items” and I can’t find the value of “Na” when I use “data.total”.
I tried to use “data” instead but it doesn’t work either......
Code:
foreach (var p in jsonbject.SelectToken("data.items"))
{
Na = "";
}
foreach (var f in jsonbject.SelectToken("data.total"))
{
total = "";
}
JSON code
{{
"data": {
"total": 125,
"items": [
{
"Na": "hdbcjd213",
}
I want to extract the value of "total" and "items" and save in the database.
In short, I want to write something like this:
foreach (var p in jsonbject.SelectToken("['data.total','data.items']"))
{
total = "";
id = "";
}
You are probably trying the wrong approach.
The best approach would be to convert the data into a poco object
public class Item
{
[JsonProperty("Na")]
public string Na { get; set; }
}
public class Data
{
[JsonProperty("total")]
public int total { get; set; }
[JsonProperty("items")]
public IList<Item> items { get; set; }
}
public class Example
{
[JsonProperty("data")]
public Data data { get; set; }
}
And then deserialize the data-
var data = JsonConvert.Deserialize<Example>("{ \"data\": ...... ")
Now you can get the data using the object data. data.Items, data.Total.
So you can write -
foreach( var item in data.Items){
var toal = data.total;
var na = item.Na;
}
Alternatively, If you only need to do is to get the values, you can use dynamic.
var data = JsonConvert.Deserialize<dynamic>("{ \"data\": ...... ");
var items = data.items;
var total = data.total;
....
foreach( var item in data.Items){
var total = data.total;
var na = item.Na;
}
but for this approach you have to cast them again whenever you use them.
I hope this helps. If this is not something you are looking for, let me know.
I trying to get the id and email list from the JSON. How can i achieve this?
My JSON string is
{
"name":"name1",
"username":"name1",
"id":505,
"state":"active",
"email":"name1#mail.com",
},
{
"name":"name2",
"username":"name2",
"id":504,
"state":"active",
"email":"name2#mail.com",
}
My code is
Dictionary<string, string> engineers = new Dictionary<string, string>();
using (StreamReader r = new StreamReader(#"D:\project\Gitlap\EngineerEmail\jsonlist5.json"))
{
using (JsonTextReader reader = new JsonTextReader(r))
{
JObject o2 = (JObject)JToken.ReadFrom(reader);
string id = o2["id"].ToString();
string email = o2["email"].ToString();
engineers.Add(email, id);
}
}
class UserItems
{
public string id { get; set; }
public string email { get; set; }
}
I can able to get the first person`s mail ID and ID details. I need to iterate this JSON and get all the mail ID and ID.
I don`t know that how to iterate this JSON. I tried some method from the internet but that was not succeeded.
How can I do?
First thing is your JSON input is not valid json, you need to fix it. There are two issues in it. Its not collection of json objects and comma is missing between two objects.
Valid json should look like below.
[{
"name":"name1",
"username":"name1",
"id":505,
"state":"active",
"email":"name1#mail.com",
},
{
"name":"name2",
"username":"name2",
"id":504,
"state":"active",
"email":"name2#mail.com",
}]
Now define a c# class representing your json object.
public class User
{
public string name { get; set; }
public string username { get; set; }
public int id { get; set; }
public string state { get; set; }
public string email { get; set; }
}
Use JSON.Net library to deserialize it as shown below.
private void button1_Click(object sender, EventArgs e)
{
if(File.Exists("json1.json"))
{
string inputJSON = File.ReadAllText("json1.json");
if(!string.IsNullOrWhiteSpace(inputJSON))
{
var userList = JsonConvert.DeserializeObject<List<User>>(inputJSON);
}
}
}
JObject o2 = (JObject)JToken.ReadFrom(reader);
foreach(var obj in o2)
{
string id = obj["id"].ToString();
string Email= obj["Email"].ToString();
engineers.Add(email, id);
}
I would recommend using the Json.NET NuGet package to accomplish this.
Firstly, create a model to represent your JSON data. Typically I would capitalize the first letter of the property names here, but to keep it consistent with the JSON, they are lower case.
public class UserData
{
public string name { get; set; }
public string username { get; set; }
public int id { get; set; }
public string state { get; set; }
public string email { get; set; }
}
You will need to add a using for Json.NET
using Newtonsoft.Json;
Finally, you can load, and deserialize your data into a strongly typed list, which you can then use to populate your engineers dictionary.
string datapath = #"D:\project\Gitlap\EngineerEmail\jsonlist5.json";
Dictionary<string, string> engineers = new Dictionary<string, string>();
List<UserData> data = new List<UserData>();
using (StreamReader r = new StreamReader(datapath))
{
string json = r.ReadToEnd();
data = JsonConvert.DeserializeObject<List<UserData>>(json);
data.ForEach(engineer => engineers.Add(engineer.email, engineer.id.ToString()));
}
As mentioned in another answer, your JSON is also badly formed. This will need correcting before it will deserialize correctly. We just need to add a comma to separate the two objects, and wrap them both in a JSON array, with []
[
{
"name":"name1",
"username":"name1",
"id":505,
"state":"active",
"email":"name1#mail.com"
},
{
"name":"name2",
"username":"name2",
"id":504,
"state":"active",
"email":"name2#mail.com"
}
]
Improvements
As your Id field is an integer, it would be better to change your dictionary from
Dictionary<string, string> engineers = new Dictionary<string, string>();
into
Dictionary<string, int> engineers = new Dictionary<int, string>();
You will then be able to simplify your ForEach query slightly. The ForEach can also be moved outside of the using() block.
data.ForEach(engineer =>
engineers.Add(engineer.email, engineer.id));
Improved solution
This includes the improvements above, I've used var for brevity.
var datapath = #"D:\project\Gitlap\EngineerEmail\jsonlist5.json";
var engineers = new Dictionary<string, int>();
var data = new List<UserData>();
using (var r = new StreamReader(datapath))
{
var json = r.ReadToEnd();
data = JsonConvert.DeserializeObject<List<UserData>>(json);
}
data.ForEach(engineer =>
engineers.Add(engineer.email, engineer.id));
try to create class that represent the data in json object for example
Class obj
{
public int Id { get ; set; }
public string email { get ; set; }
public string username { get ; set; }
public string state { get ; set; }
public string email { get ; set; }
}
then
using System.Web.Script.Serialization;
var js = new JavaScriptSerializer();
List<obj> list = js.Deserialize<List<obj>>(jsonString);
after that you can access all list items id and email by using foreach
I have the following JSON coming back from a remote API (I cannot modify the JSON returned)
{
"APITicket": {
"location": "SOMEVALUE",
"ticket": "SOMEVALUE"
}
}
Now using JSON.Net to convert to this to a model I have to create 2 models.
public class TicketModel
{
public string location { get; set; }
public string ticket { get; set; }
}
public class TicketContainer
{
public TicketModel APITicket { get; set; }
}
and do something like..
var myObject = JsonConvert.DeserializeObject<TicketContainer>(this.JSONResponse);
and this works well - my problem arises when I have around 50 calls to make to the API and really dont fancy creating a second 'Container' for each. Is there a way to bind the example above directly to the TicketModel?
You can do it this way:
var json = #"
{
'APITicket': {
'location': 'SOMEVALUE',
'ticket': 'SOMEVALUE'
}
}";
//Parse the JSON:
var jObject = JObject.Parse(json);
//Select the nested property (we expect only one):
var jProperty = (JProperty)jObject.Children().Single();
//Deserialize it's value to a TicketModel instance:
var ticket = jProperty.Value.ToObject<TicketModel>();
use Newtonsoft's JArray to customize ur json before deserialize
public List<APITicket> JsonParser(string json)
{
Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(json);
var list = new List<APITicket>();
foreach(var item in jArray)
{
list.Add(
new APITicket { location = item["APITicket"]["location"],
ticket = item["APITicket"]["ticket"]
}
);
}
return list;
}
Modify the JSON so it looks like this
{
"location": "SOMEVALUE",
"ticket": "SOMEVALUE"
}
and do
List<TicketModel> tickets = JsonConvert.DeserializeObject<List<TicketModel>>(this.JSONResponse);
or even
Dictionary<string, string> tickets = JsonConvert.DeserializeObject<Dictionary<string, string>>(this.JSONResponse);
so you don't need any models.