Unity C#: parse JSON file into data structure [duplicate] - c#

This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 5 years ago.
I'm trying to create a custom revision quiz program in Unity C# which allows users to load questions into the program using JSON files, structured as below:
{
"question": [
{
"title": "What wave characteristic is measured on the vertical axis?",
"answers": {
"correct": "Amplitude",
"wrong": [
"Frequency",
"Period",
"Speed"
]
}
},
{
"title": "Which of these is a vector quantity?",
"answers": {
"correct": "Velocity",
"wrong": [
"Speed",
"Time",
"Mass"
]
}
}
]
}
I've managed to get my program reading from a file using a StreamReader, but am having a lot of trouble trying to get it into a single data structure.
I have seen other solutions using classes and manually defining structures for their solutions, but I don't know how to go about implementing this for a) as complex a structure as this and b) a structure that can have an arbritrary number of items in it (I'd like to support any number of questions). If the best way is to define these classes, how do I go about referencing items inside them? In the past I've parsed JSON using Python 3.6's json library's json.loads() function, and that worked perfectly, creating a single multidimensional array / dictionary structure that I could work with easily.
To put it simply, I currently have a string that I've read from a file with JSON data in it. How do I synthesise this into a single array that I can easily access using, eg, questions[question][0]["title"], which would return "What wave characteristic is measured on the vertical axis?" in the above case?

Use this site and generate your model.
public class Answers
{
public string correct { get; set; }
public List<string> wrong { get; set; }
}
public class Question
{
public string title { get; set; }
public Answers answers { get; set; }
}
public class RootObject
{
public List<Question> question { get; set; }
}
var model = JsonConvert.DeserializeObject<RootObject>(jsonstring);
That is all
BTW: You can also access to those properties dynamically without declaring any model
var model = JObject.Parse(jsonstring);
var title0 = (string)model["question"][0]["title"];
PS: I used Json.net

I think one way you can create a single data structure in your application by using the JSON given above is using the "paste special feature" of visual studio.Once you select it from the edit menu you have option to create class from JSON by just pasting any valid JSON.
I get the following class after pasting your JSON related to Questions:-
public class Rootobject
{
public Question[] question { get; set; }
}
public class Question
{
public string title { get; set; }
public Answers answers { get; set; }
}
public class Answers
{
public string correct { get; set; }
public string[] wrong { get; set; }
}
Single Rootobject class consists of the Question array.There different classes automatically created by visual studio related to Question and Answers.
You can deserialize the JSON values into your RootObject using JSON.NET desrialization:
var questions= JsonConvert.DeserializeObject<RootObject>(jsonString);

Related

C# Json Generic "Tiered" Deserialize

I'm trying to deserialize a JSON file into a generic stack of serialized objects so I can easily make a sort of tree view using a for loop.
I've done a little Googling over the past couple hours but can't seem to find anything that would allow a truly generic approach, as all seem to require using pre-declared variables, setting the max depth of the tree.
There are many online generic JSON viewers (though no code is provided) so I am sure this is possible, I just have no idea how.
The file I'm currently working with as an example is below, as is an example of how I'm trying to get this structured.
{"arcanePrefs":[{"name":"playerWalkingSpeed","category":"player","value":"6"},{"name":"playerRunningSpeed","category":"player","value":"8"},{"name":"playerLookSpeed","category":"player","value":"12"},{"name":"playerHorTurnSpeed","category":"player","value":"2"},{"name":"playerVerTurnSpeed","category":"player","value":"2"},{"name":"playerJumpHeight","category":"player","value":"6"},{"name":"playerVertLimit","category":"player","value":"80"},{"name":"playerAirCtrl","category":"player","value":"True"},{"name":"playerGravMod","category":"player","value":"1.5"},{"name":"playerHBobWlkSpd","category":"player","value":"0.18"},{"name":"playerHBobRunSpd","category":"player","value":"0.35"},{"name":"playerHBobHgt","category":"player","value":"0.4"},{"name":"playerHCant","category":"player","value":"True"},{"name":"playerReloadSpeed","category":"player","value":"1"},{"name":"playerUseRadius","category":"player","value":"0.5"},{"name":"playerWasteHealth","category":"player","value":"False"},{"name":"playerWasteArmor","category":"player","value":"False"},{"name":"playerWasteAmmo","category":"player","value":"False"},{"name":"playerHeight","category":"player","value":"1.6"},{"name":"playerBaseHealth","category":"player","value":"100"},{"name":"playerMaxHealth","category":"player","value":"250"},{"name":"playerbaseArmor","category":"player","value":"100"},{"name":"playerMaxArmor","category":"player","value":"150"},{"name":"playerWeaponSoftDrag","category":"player","value":"True"},{"name":"enemyStunLock","category":"enemy","value":"True"},{"name":"enemyGunshotDetectRaduis","category":"enemy","value":"40"},{"name":"worldWaterFallDmg","category":"world","value":"False"},{"name":"worldCanShootSwitches","category":"world","value":"True"},{"name":"worldLavaDamagePerFrame","category":"world","value":"1"},{"name":"cameraFOV","category":"camera","value":"80"},{"name":"cameraToneMapping","category":"camera","value":"True"},{"name":"cameraCustomPixel","category":"camera","value":"True"},{"name":"cameraPixelRes","category":"camera","value":"res360p"},{"name":"cameraDither","category":"camera","value":"True"},{"name":"cameraDitherStrength","category":"camera","value":"0.95"},{"name":"cameraBloom","category":"camera","value":"True"},{"name":"cameraBloomInt","category":"camera","value":"5"},{"name":"cameraUnderwaterCol1","category":"camera","value":"0.1921569;0.3921569;0.4509804;1"},{"name":"cameraUnderwaterCol2","category":"camera","value":"0.3137255;0.5882353;0.5882353;1"},{"name":"cameraUnderlavaCol1","category":"camera","value":"0.9019608;0.2313726;0;1"},{"name":"cameraUnderlavaCol2","category":"camera","value":"0.9019608;0.6666667;0.3529412;1"},{"name":"cameraCshrCol","category":"camera","value":"0.4901961;0.4901961;0.4901961;1"},{"name":"cameraCshrTgtCol","category":"camera","value":"0.7803922;0;0;1"},{"name":"arcaneLimitFPS","category":"engine","value":"True"},{"name":"arcaneFpsLimit","category":"engine","value":"-1"},{"name":"engineUIScale","category":"engine","value":"0.7"},{"name":"srcBHopping","category":"sem","value":"False"}],"arcaneControls":[{"name":"contForward","key":119},{"name":"contLeft","key":97},{"name":"contBackward","key":115},{"name":"contRight","key":100},{"name":"contRotLeft","key":113},{"name":"contRotRight","key":101},{"name":"contJump","key":32},{"name":"contLookUp","key":280},{"name":"contLookDown","key":281},{"name":"contSprintHold","key":304},{"name":"contSprintToggle","key":301},{"name":"contCrouchHold","key":306},{"name":"contCrouchToggle","key":99},{"name":"contComFire","key":323},{"name":"contComFireAlt","key":305},{"name":"contComSFire","key":324},{"name":"contComSFireAlt","key":303},{"name":"contComReload","key":114},{"name":"contComPrevWeap","key":326},{"name":"contComNextWeap","key":327},{"name":"contComInspectWeap","key":103},{"name":"contDebug","key":96}]}
What I'm trying to do
I do not use Unity, but they seem to provide newtonsoft which is a powerfull serializer / deserializer library for json link
For your use case, you want to convert json to a list of objet I think, so deserialize in this case.
To obtain an object representation of your json string you can go like
string json; // you data here
Arcane arcane=Newtonsoft.Json.JsonConvert.DeserializeObject<Arcane>(json);
public class Arcane
{
public List<ArcanePref> arcanePrefs { get; set; }
public List<ArcaneControl> arcaneControls { get; set; }
}
public class ArcanePref
{
public string name { get; set; }
public string category { get; set; }
public string value { get; set; }
}
public class ArcaneControl
{
public string name { get; set; }
public int key{ get; set; }
}
With the arcane object you can then access the acranePrefs and arcaneControls list.
To represent the json data in a tree view fashion with Unity, I found the tree view api
Which seem the most straight foward way to go for a tree view representation
Once you have your objects, it should be more or less simple.
Concerning riffnl comment, I do not have any idea what the end goal is, or what is the source you are using ^^'
Hope it helps !

JSON.NET deserialize JSON then format string [duplicate]

This question already has answers here:
running a transformation on a Json DeserializeObject for a property
(2 answers)
Closed 3 years ago.
I have the following JSON:
{
"lastOcurrences":[
{
"myString":"16726354"
},
{
"myString":"66728744"
},
{
"myString":"91135422"
}
]
}
and I have a class to deserialize it on:
public class JsonObject
{
public List<LastOcurrence> LastOcurrences { get; set; }
}
public class LastOcurrence
{
public string MyString { get; set; }
}
Upon deserializing it with JsonConvert.DeserializeObject<T>(json), I'd like to be able to format the string myString, to store 167-263-54, instead of 16726354.
What solution would please my soul: Using attributes on the properties, something of the likes of JsonConverter, but...
What i'd like to avoid doing: I would not like to use reflection to iterate through every property, only to then read the attribute and apply the formatting. Is there any way of doing this 'automatically' with JsonConvert?
One possible solution is to use custom getters and setters for this and when it is deserialized you keep the raw data stored. This will do JIT formatting. Depending on the usage of this data this could be much quicker however if there are a lot of repeated reads of the same data then this may be a bit slower.
public class LastOcurrence
{
private string _myString;
public string MyString
{
get { return Regex.Replace(_myString, #"^(.{ 3})(.{ 3})(.{ 2})$", "$1-$2-$3"); }
set { _myString = value; }
}
}

Get tags names from json file as a variable in a class

I am using C# MVC
I am importing a Json file from a location to an Rest API. In order to display the data. the program needs to know the name of the tags.
I would like to know if there is a way to get the tags from the files in an array of strings and declare them via program instead of manually inputting them.
Current C# Code
public class Person
{
public int Id { get; set; }
public int SomeID { get; set; }
public int Number { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
Current Json File:
[{"Id":212,"SomeID":71,"Number":0,"Name":"Mr Jones Mones","Address":"21, street, city"}
So as mentioned this code words fine. But, as I am importing data, the tags may contain different information and I would like to have the public declaration in a way that I can import any file to the API and be able to edit and export it.
Thank you
If you use JSON.net you can parse out json into a JObject then iterate over it's properties like so, however each property value can be any type of object so you'd need to write something to either recursively listed out nested objects or check if values are strings and only take them if they are etc.
var obj = JObject.Parse("{ \"test\": \"test\", \"test1\": \"test1\", \"test2\": \"test2\" }");
foreach (var prop in obj.Properties())
{
Console.WriteLine(prop.Name);
}
You can use JsonConvert like this:
Person person = JsonConvert.DeserializeObject<Person>(jsonString);
Read the docs for JsonConvert for more info.

Auto-generate C# classes from JSON, including property initializers

There are a number of great ways to auto-generate C# code from JSON, such as here and here.
However, the resulting code doesn't include property initializers. For example, the following JSON:
{
"Name" : "Blastoise"
}
gets deserialized to this:
public class RootObject
{
public string Name { get; set; }
}
Presumably this is by design, since the values used in the JSON will probably be overridden anyways, so adding initializers might just annoy people who don't want them.
But what if I want that? Short of manually adding every value by hand, is there a way to deserialize JSON to the following?
public class RootObject
{
public string Name { get; set; } = "Blastoise";
}
Obviously in this case a manual edit is easy, but manual editing becomes tedious for larger JSON objects.
is there a way to deserialize JSON to the following?
Using the source code of the converter you mentioned.
A quick change at the line 204
sw.WriteLine(prefix + "public {0} {1} {{ get; set; }} = {2};", field.Type.GetTypeName(), field.MemberName, field.GetExamplesText());
gives me the result similar to what you described
internal class SampleResponse1
{
[JsonProperty("Name")]
public string Name { get; set; } = "Blastoise";
}

.NET classes needed to deserialize JSON string [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Parse JSON in C#
I'm trying to deserialize a JSON string from the openlibrary.org in an ASP.NET (4.5) web application using JSON.NET.
My aim is to be able to read the 5 properties below from a single .Net object.
The example JSON
I have is:
{"ISBN:0201558025":
{
"bib_key": "ISBN:0201558025",
"preview": "noview",
"thumbnail_url": "http://covers.openlibrary.org/b/id/135182-S.jpg",
"preview_url": "http://openlibrary.org/books/OL1429049M/Concrete_mathematics",
"info_url": "http://openlibrary.org/books/OL1429049M/Concrete_mathematics"
}
}
I can get it to work fine without the first line, but I'm a bit lost trying to work out how I should structure my classes.
I'm new to JSON and haven't played with C#/VB.NET in a few years so getting very lost.
Update
I have the following code:
Dim url = "http://openlibrary.org/api/books?bibkeys=ISBN:0201558025&format=json"
Dim webClient = New System.Net.WebClient
Dim json = webClient.DownloadString(url)
Dim book As Book = JsonConvert.DeserializeObject(Of Book)(json)
And the class Book:
Public Class Book
Public bib_key As String
Public preview As String
Public preview_url As String
Public info_url As String
End Class
However, book turns up empty.
There is a website called json2csharp - generate c# classes from json:
public class RootObject
{
public string bib_key { get; set; }
public string preview { get; set; }
public string thumbnail_url { get; set; }
public string preview_url { get; set; }
public string info_url { get; set; }
}
The json format is a little off, remove the {"ISBN:0201558025": since you have the ISBN as the bib_key
Try using JSON.Net
or
JavaScriptSerializer Class
or
DataContractSerializer class
I think it can be deserialized as a Dictionary.
new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Dictionary<string, BookInfoClass>>(jsonString);

Categories