This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 4 years ago.
I am not sure how to accomplish this. I am getting some users from an www request like this:
Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Authorization", "Basic "+System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes("user*pass")));
WWW www = new WWW("https://somedomain.com:8000/users", null, headers);
yield return www;
Debug.Log(www.text);
The debug returns this:
[{"user_id":"ho896ty6","user_name":"Mikje Flanders","age":43},{"user_id":"ft357hj","user_name":"Anna Simpson","age":56}]
Now, I have an object like this:
public class userData
{
string user_id;
string user_name;
int age;
}
which i would like to get the data into, but not sure when the json is an array. I tried like this, but with no luck:
userData thisUser = JsonUtility.FromJson<userData>(www.text);
Hope someone can help me with this and thanks in advance :-)
1) Install Newtonsoft.json from Nuget Package Manager and add reference to your program
like using Newtonsoft.Json;
2) This is your user model class
public class User
{
public string user_id { get; set; }
public string user_name { get; set; }
public int age { get; set; }
}
3) Then deserialize your json to your model like
class Program
{
static void Main(string[] args)
{
//Sample json i get in variable
var json = #"[{'user_id':'ho896ty6','user_name':'Mikje Flanders','age':43},{'user_id':'ft357hj','user_name':'Anna Simpson','age':56}]";
//This line convert your string json to c# object
List<User> userList = JsonConvert.DeserializeObject<List<User>>(json);
//Loop through to get each object inside users list
foreach (User user in userList)
{
Console.WriteLine($"user_id: {user.user_id}, user_name: {user.user_name}, age: {user.age}");
}
Console.ReadLine();
}
}
Output:
Try once may it help you.
you will have to parse the Json using delimiters, unless your using visual studio in that case, check your nuget for Newtonsoft.Json with this package installed you can:
Using NewtonSoft.Json;
List udat = JsonConvert.DeserializeObject>(json);
foreach( userData data in udat){
//do something here to each item;
}
using jsoneditoronline
[
{
"user_id": "ho896ty6",
"user_name": "Mikje Flanders",
"age": 43
},
{
"user_id": "ft357hj",
"user_name": "Anna Simpson",
"age": 56
}
]
i cleaned up your code a little so you can see what your doing.
added some getters and setters to your class...
it looks like your getting more than one userData return in your request, so you may need a list or array. if you need help with that let me know!
public class userData
{
public string user_id {get;set;}
public string user_name{get;set;}
public int age{get;set;}
}
public class userList
{
public List<userData> users{get;set;}
}
Related
I am trying to make a multi-subject quiz game for children using unity3D and questions and answers are stored in a json file. Now i want to create an object named "science" and "maths" and want to store their respective questions in them and when i want to access science i could loop and find and just store the science question in my string instead of reading the whole json file.
here is my json file.
Science ={
"CourseName":"Science",
"No_Of_Ques":4,
"Ques_Data":[
{ "Quesion":"which is the biggest planet in the solar system?",
"Answer":"jupiter",
"options":["mars","earth","venus","jupiter"]
},
{ "Quesion":"How many planets are there in solar system?",
"Answer":"Eight",
"options":["Seven","Nine","Five","Eight"]
},
{ "Quesion":"which is the closest planet to the sun?",
"Answer":"mercury",
"options":["mars","saturn","venus","mercury"]
},
{ "Quesion":"How many moons does jupiter have?",
"Answer":"12",
"options":["5","13","9","12"]
}
]
}
and this is how i have been acessing it so far
path = Application.dataPath + "/QnA.json";
string json = File.ReadAllText(path);
Course c1 = JsonUtility.FromJson<Course>(json);
return c1;
Course and needed serializable Classes:
[Serializable] public class Course
{
public string CourseName;
public string No_Of_Ques;
public QnA[] Ques_Data;
}
[Serializable]
public class QnA
{
public string Quesion;
public string Answer;
public string[] options;
}
i have tried so many things like Deserialization and Jobject asset but none of them seem to work and every implementation that i have found on the internet has the json data in the same file as the c# code but i can not do that as my json contains hundreds of lines of data. kindly help me out a little.
Create a course class in which create getter and setter functions for all of your json keys, for example:
if your json file is like that:
[
{
"CourseName": "Science",
"No_Of_Ques": 1,
...
},
{
"CourseName": "Math",
"No_Of_Ques": 1,
...
}
]
then course class should be:
public class Course
{
public string CourseName { get; set; }
public int No_Of_Ques { get; set; }
}
In your main class or anywhere you can access your selected course, here i am using only 0 index of a json, you can also loop through whole json and find your desirable course.
StreamReader to read a file
convert it to json
Deserialize the json as per your course
Console it
using (StreamReader r = new StreamReader("../../../js.json"))
{
string json = r.ReadToEnd();
List<Course> ro = JsonSerializer.Deserialize<List<Course>>(json);
Console.WriteLine(ro[0].CourseName);
}
I added json file in the same dire where my mainClass file is, as StreamReader requires an absolute path therefore I used an absoulte path for my json file.
using (StreamReader r = new StreamReader("../../../js.json"))
Require Libs
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
Note: I created a console app, not sure your app type
If you want to store multiple courses in your file you will need to store them as json array (as you do with questions):
[
{
"CourseName":"Science",
"No_Of_Ques":1,
"Ques_Data":[
{
"Question":"which is the biggest planet in the solar system?",
"Answer":"jupiter",
"options":[
"mars",
"jupiter"
]
}
]
},
{
"CourseName":"Math",
"No_Of_Ques":1,
"Ques_Data":[
{
"Question":"2 + 2",
"Answer":"4",
"options":[
"4",
"0"
]
}
]
}
]
then you can deserialize them with next structure(for example):
public class Course
{
[JsonProperty("CourseName")]
public string CourseName { get; set; }
[JsonProperty("No_Of_Ques")]
public long NoOfQues { get; set; }
[JsonProperty("Ques_Data")]
public QuesDatum[] QuesData { get; set; }
}
public class QuesDatum
{
[JsonProperty("Question")]
public string Question{ get; set; }
[JsonProperty("Answer")]
public string Answer { get; set; }
[JsonProperty("options")]
public string[] Options { get; set; }
}
var courses = JsonConvert.DeserializeObject<List<Course>>(jsonString);
var course = courses.Where(...).FirstOrDefault();
Or try to use json path:
var course = JToken.Parse(jsonString)
.SelectToken("$[?(#.CourseName == 'Math')]")
.ToObject<Course>();
As for jsonString you can obtain it in any way, reading from file for example.
P.S.
There was typo "Quesion" -> "Question"
To serialize and deserialize objects you have to create a C# class (in your case should be Course class) that can be [Serializable].
First your Json should be a valid one, which it is, you can validate it here.
To serialize and deserialize you can use JsonUtility to certain point, cause it doesn't deserialize jagged arrays, complex objects etc. I recommend to use third party softwares like Newtonsoft or implement your own serialization/deserialization method for your way.
Edit:
Your JSON file should be without the "Science=" part, should look like:
{
"CourseName":"Science",
"No_Of_Ques":4,
"Ques_Data":[
{ "Quesion":"which is the biggest planet in the solar system?",
"Answer":"jupiter",
"options":["mars","earth","venus","jupiter"]
},
{ "Quesion":"How many planets are there in solar system?",
"Answer":"Eight",
"options":["Seven","Nine","Five","Eight"]
},
{ "Quesion":"which is the closest planet to the sun?",
"Answer":"mercury",
"options":["mars","saturn","venus","mercury"]
},
{ "Quesion":"How many moons does jupiter have?",
"Answer":"12",
"options":["5","13","9","12"]
}
]
}
Edit:
For your comment I think you got a misunderstood of how to handle the relation between files and variables.
You want to have (or at least it seems like this) one file for every type of course, so in this case, the text above will be your Science.json file.
When you store that information, you will do similar of what you do:
path = Application.dataPath + "/QnA.json";
string json = File.ReadAllText(path);
Course scienceCourse = JsonUtility.FromJson<Course>(json); //notice the name of the variable!
So as you can see for the variable name, you will read EVERY SINGLE JSON for every course.
The other way to do that, is to store all the courses on the same Json file, and then get them as an ARRAY of Courses -> Course[] allCourses
Using Science={...} to define your object is where you get confused about object definitions. It is not a Science object. It is a Course object.
It should be more like
{
"Courses" :
[
{
"CourseName" : "Science",
...
},
{
"CourseName" : "Maths",
...
}
]
}`.
Wrap it with:
"Quiz" :
{
"Courses" :
[
{
"CourseName" : "Science",
...
},
{
"CourseName" : "Maths",
...
}
]
}
and use
[Serializable]
public class Quiz
{
public Course[] courses;
}
To hold it as a C# object.
From here you can access your courses by quiz.Courses[0].Questions[17] or write helper methods in Quiz class to call courses by enums like quiz.GetCourse(CourseCategory.Science).Questions[8].
I also suggest using Questions instead of Question_Data. That is more object friendly and helps you semantically.
As an additional suggestion, instead of dumping all of the quiz in a single JSON, you may consider sending a single Course object depending on the course, requested using a query like http://myquizserver.com/quiz.php?course=science. Since you mentioned hundreds of lines of JSON, you may also consider getting data question by question.
I am new in json. I want information of different users and add them to a dataGridView or dataTable or dataSet in c# (.net development). Information sample is (The json is valid):
{
"JrPwbApfIHbQhCUmVIoiVJcPYv93": {
"address": "Jessore",
"name": "Dev"
},
"iBRZAyn8TQTOgKTcByGOvJjL9ZB3": {
"address": "Bogra",
"name": "Kumar Saikat"
}
}
I want them like this :
User1 | Jessore | Dev
User2 | Bogra | Kumar Saikat
Even it would help if I could make a list for all of them.
I believe I was able to deserialise them (not sure at all) by
var model = JsonConvert.DeserializeObject<user>(json);
where user is a class.
public class Item
{
public string name;
public string address;
}
from this question-answer. From this tutorial I am able to get values if property is known. But in my case my property would be unknown, (string "User1","User2" would be random, since I will get them from a database). Any help and light on this matter would be greatly appreciated. Thank you in advance.
You're looking at a JSON dictionary, so just deserialize it as such:
public static Dictionary<string,Item> ParseJson(string source)
{
return JsonConvert.DeserializeObject<Dictionary<string,Item>>(source);
}
If you call it like this:
public static void Main()
{
var input = #"{'JrPwbApfIHbQhCUmVIoiVJcPYv93': {'address': 'Jessore','name': 'Dev' }, 'iBRZAyn8TQTOgKTcByGOvJjL9ZB3': {'address': 'Bogra','name': 'Kumar Saikat'}}";
var result = ParseJson(input);
foreach (var r in result)
{
Console.WriteLine("Key={0};Name={1};Address={2}", r.Key, r.Value.name, r.Value.address);
}
}
The output is:
Key=JrPwbApfIHbQhCUmVIoiVJcPYv93;Name=Dev;Address=Jessore
Key=iBRZAyn8TQTOgKTcByGOvJjL9ZB3;Name=Kumar Saikat;Address=Bogra
This example dumps the list to the console, but you could easily modify the for loop to add to a list instead.
See my example on DotNetFiddle
Can use the nuget package Newtonsoft.Json. This code gives you what you are looking for:
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
var json =
"{\"JrPwbApfIHbQhCUmVIoiVJcPYv93\":{\"address\":\"Jessore\",\"name\":\"Dev\"}," +
"\"iBRZAyn8TQTOgKTcByGOvJjL9ZB3\":{\"address\":\"Bogra\",\"name\":\"Kumar Saikat\"}}";
var o = JsonConvert.DeserializeObject(json);
var items = new List<Item>();
foreach (dynamic x in o as IEnumerable)
{
var i = new Item();
var y = x.First;
i.Name = y.name.Value;
i.Address = y.address.Value;
items.Add(i);
}
}
public class Item
{
public string Name { get; set; }
public string Address { get; set; }
}
}
}
Your situation is a bit strange as those autocreated names like
"JrPwbApfIHbQhCUmVIoiVJcPYv93" or else it's easier, but should be fairly easy code.
Keep in mind I use "dynamic" there which means problems will hit you at runtime NOT design time as it's not checked.
The correct way to deserialize would be as below
var model = JsonConvert.DeserializeObject<Dictionary<string, Item>>(data);
In the code sample you have posted, your "user" class name is Item but you are trying to deserialize using "User" in your code. Also please note that you cannot directly directly deserialize data into users list as it is present as a value of some random strings.
var model = JsonConvert.DeserializeObject<user>(json);
For your code to deserialize correctly, your json format should be as below :
{
{
"address": "Jessore",
"name": "Dev"
},
{
"address": "Bogra",
"name": "Kumar Saikat"
}
}
I have a Json service I cannot alter as it is not mine.
Their Json is a formatted in a way that parsing it is difficult. It looks something like this.
"people": {
"Joe Bob": {
"name": "Joe Bob",
"id": "12345"
},
"Bob Smith": {
"name": "Bob Smith",
"id": "54321"
}
},
I would really prefer this was laid out like a JSon array, however it presently is not.
I am wondering the best approach here. Should I alter the Json to look like an array before I parse it or load up the ExtensionData and parse it from that?
There are other items in the feed that I do not have issue with. Just stuck with this one section.
Thanks
You can use json.net to deserialize the data (the json you pasted, and doing only one parsing, without modifying anything).
using dynamic foo = JsonConvert.DeserializeObject<dynamic>(data)
than, you can iterate the list using foo.people, accessing the Name and Value.
you can create a class (if you know what the schema is, and to deserialize the data into a list of the given class such as:
public class People
{
[JsonProperty(PropertyName="people")]
public IDictionary<string, Person> Persons { get; set; }
}
public class Person
{
[JsonProperty(PropertyName="name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
}
and than call:
var obj = JsonConvert.DeserializeObject<People>(data);
foreach (var item in obj.Persons.Values)
{
//item is instance of Person
}
Another good and possible option will be:
How can I navigate any JSON tree in c#?
I get the following JSON that I am trying to convert to a business object using RestSharp
{
"valid":true,
"data":[
{
"dealerId":"4373",
"branchId":"4373",
}
]
}
I wish to convert to:
public class Dealer
{
public string dealerId ;
public string branchId;
}
But this fails, though the JSON is fine:
var client = new RestClient("http://www.????.com.au");
var request = new RestRequest(string.Format("service/autocomplete/dealer/{0}/{1}.json", suburb.PostCode, suburb.City.Trim().Replace(" ", "%20")), Method.GET);
var response2 = client.Execute<Dealer>(request);
return response2.Data;
Your business object doesn't match the response JSON you are getting back. If you want your response to serialize, your C# object would look something like
public class DealerResponse
{
public bool valid { get;set; }
List<Dealer> data { get;set; }
}
public class Dealer
{
public string dealerId;
public string branchId;
}
I haven't tested this code, but even though you are only interested in the information in 'data', your response C# objects still need to represent the whole JSON response to serialize correctly.
Hope that helps.
Does anyone know how to convert a string which contains json into a C# array. I have this which reads the text/json from a webBrowser and stores it into a string.
string docText = webBrowser1.Document.Body.InnerText;
Just need to somehow change that json string into an array. Been looking at Json.NET but I'm not sure if that's what I need, as I don't want to change an array into json; but the other way around. Thanks for the help!
just take the string and use the JavaScriptSerializer to deserialize it into a native object. For example, having this json:
string json = "[{Name:'John Simith',Age:35},{Name:'Pablo Perez',Age:34}]";
You'd need to create a C# class called, for example, Person defined as so:
public class Person
{
public int Age {get;set;}
public string Name {get;set;}
}
You can now deserialize the JSON string into an array of Person by doing:
JavaScriptSerializer js = new JavaScriptSerializer();
Person [] persons = js.Deserialize<Person[]>(json);
Here's a link to JavaScriptSerializer documentation.
Note: my code above was not tested but that's the idea Tested it. Unless you are doing something "exotic", you should be fine using the JavascriptSerializer.
using Newtonsoft.Json;
Install this class in package console
This class works fine in all .NET Versions, for example in my project: I have DNX 4.5.1 and DNX CORE 5.0 and everything works.
Firstly before JSON deserialization, you need to declare a class to read normally and store some data somewhere
This is my class:
public class ToDoItem
{
public string text { get; set; }
public string complete { get; set; }
public string delete { get; set; }
public string username { get; set; }
public string user_password { get; set; }
public string eventID { get; set; }
}
In HttpContent section where you requesting data by GET request
for example:
HttpContent content = response.Content;
string mycontent = await content.ReadAsStringAsync();
//deserialization in items
ToDoItem[] items = JsonConvert.DeserializeObject<ToDoItem[]>(mycontent);
Yes, Json.Net is what you need. You basically want to deserialize a Json string into an array of objects.
See their examples:
string myJsonString = #"{
"Name": "Apple",
"Expiry": "\/Date(1230375600000+1300)\/",
"Price": 3.99,
"Sizes": [
"Small",
"Medium",
"Large"
]
}";
// Deserializes the string into a Product object
Product myProduct = JsonConvert.DeserializeObject<Product>(myJsonString);
Old question but worth adding an answer if using .NET Core 3.0 or later. JSON serialization/deserialization is built into the framework (System.Text.Json), so you don't have to use third party libraries any more. Here's an example based off the top answer given by #Icarus
using System;
using System.Collections.Generic;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var json = "[{\"Name\":\"John Smith\", \"Age\":35}, {\"Name\":\"Pablo Perez\", \"Age\":34}]";
// use the built in Json deserializer to convert the string to a list of Person objects
var people = System.Text.Json.JsonSerializer.Deserialize<List<Person>>(json);
foreach (var person in people)
{
Console.WriteLine(person.Name + " is " + person.Age + " years old.");
}
}
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
}
}
One Situation that wasn't covered in the other responses is when you don't know the type of what the JSON object contains. That was my case as I needed to be able to NOT type it and leave it dynamic.
var objectWithFields = js.Deserialize<dynamic[]>(json);
Note: it is definitely preferred to have a type, in some cases, it is not possible, that's why I added this answer.