Reading a JSON file into an object C# - c#

I have a JSON list of players for a game. I need the program to be able to read the JSON file and give me the list of players. Then I can use this list of players to get each player's name and who they are following.
{
"Version": "1",
"Users": [
{
"UserName": "CoolDude",
"Following": [ "SniperElitez", "IamAwesome" ]
},
{
"UserName": "GamerChick",
"Following": [ "IamAwesome", "NoWayBro", "WowWhoMe", "SniperElitez", "SurfingIsFun", "NowUTry" ]
},
{
"UserName": "SurfingIsFun",
"Following": [ "WowWhoMe" ]
},
{
"UserName": "IamAwesome",
"Following": [ "GamerChick", "NoWayBro" ]
},
{
"UserName": "NowUTry",
"Following": [ "GamerChick", "SniperElitez" ]
},
{
"UserName": "SniperElitez",
"Following": [ "SurfingIsFun", "IamAwesome" ]
},
{
"UserName": "WowWhoMe",
"Following": [ "NoWayBro", "GamerChick", "SniperElitez" ]
},
{
"UserName": "NoWayBro",
"Following": [ "GamerChick", "IamAwesome", "SniperElitez" ]
}
]
}
Here is the code I'm trying to use currently
Player Class
class Player
{
public string UserName { get; set;}
public List<string> Following { get; set;}
}
PlayerList Class
class PlayerList
{
public List<Player> pList { get; set; }
}
Main
{
string json = File.ReadAllText("friends.json");
// this gives me a playerList object
PlayerList playerList = JsonConvert.DeserializeObject<PlayerList>(json);
}
Supposedly the PlayerList object is not null but the List is empty. If anyone can tell me how to turn the JSON into the PlayerList object and then from there, get player's variables like UserName, I would greatly appreciate it!

Visual Studio has a nice feature for parsing XML / JSON... namely, if you copy an XML or a JSON to your clipboard then you can use Edit -> Paste Special -> Paste JSON As Classes command and have VS automatically generate valid model classes.
In case of your JSON this is the output my VS generated:
public class Rootobject
{
public string Version { get; set; }
public User[] Users { get; set; }
}
public class User
{
public string UserName { get; set; }
public string[] Following { get; set; }
}
Try that.
Also, you're using JsonConvert, which appears to be something by Newtonsoft. I have no idea if it's a good library or not, but there ARE .NET classes which are capable of deserializing JSON. The linked question offers one method. Another is to use a DataContractJsonSerializer, albeit I think the model classes would need to have the [DataContract] and [DataMember] attributes added to them to work with that.

The reason is that in the json doc the attribute is called "Users" and in your code you have called it "pList".
There are two solutions to this:
Rename PlayerList.pList to PlayerList.Users
Add a JsonProperty attribute on the property to set its name like this:
class PlayerList
{
[JsonProperty(PropertyName = "Users")]
public List pList { get; set; }
}

I was able to get this working by following what was stated in the question at the following link:
How to deserialize an JObject to .NET object
Here is my code:
var playerList = JsonConvert.DeserializeObject(json);
JObject jObject = ((JObject)playerList);
PlayerList users = jObject.ToObject<PlayerList>();
I also renamed the pList to Users on the PlayerList Class.

Related

How to deserialize a JSON

I am attempt to use an API that use the follow example structure for their returned json:
[{
"name":"Firs",
"id":"0",
"data": {"scale":"1","size":"500"}
},
{
"name":"Second",
"id":"1",
"data":"222"
}]
Upade "[ ]"
But I can not figure out how to get it to be happy with the provided structure.
Using Newtonsoft I am able to Serialize and Deserialize a model shown below:
List<RequestJson> requestJson = JsonConvert.DeserializeObject<List<RequestJson>>(json);
public class GetData
{
public int Scale { get; set; }
public int Size { get; set; }
}
public class RequestJson
{
public string Name { get; set; }
//Problem is here
public GetData Data { get; set; }
}
Your JSON is not valid. The Data property does not match the object type.
Correct JSON:
[{
"name":"Firs",
"id":"0",
"data": {"scale":"1","size":"500"}
},
{
"name":"Second",
"id":"1",
"data": {"scale":"2","size":"600"}
}]

Generate JsonSchema from a class hierarchy in C#

I have a class hierarchy that I want to serialize to json in a tagged union in an array.
class BaseComponent
{
public string Id { get; set; }
}
class Child1: BaseComponent
{
public string Child1Prop { get; set; }
}
class Child2: BaseComponent
{
public string Child2Prop { get; set; }
}
class Wrapper
{
public List<BaseComponent> Components { get; set; }
}
Sample json
{
"components": [
{
"id": "id-1",
"type": "Child1",
"child2Prop": "Hello"
},
{
"id": "id-2",
"type": "Child2",
"child2Prop": "world"
},
]
}
The hierarchy is likely to change, and I want to publish a nice Json Schema for validation and manual editing of the json files in VSCode. Is there any reasonable tools that lets me generate this? Or even just some strongly typed json schema C# classes that i can use to create the schema from reflection.
My Nuget package JsonSchema.Net.Generation is built for generating schemas from C# code.
The docs and a playground can be found on https://json-everything.net/json-schema

How do I parse json objects so that I can get all the values correctly

So I got this JSON string which looks like this:
{"success":false,"errors":[{"name":["Username "admin" has already been taken."],"email":["Email is not a valid email address."]}],"data":[]}
or, more readably:
{
"success": false,
"errors": [
{
"name": [
"Username "admin" has already been taken."
],
"email": [
"Email is not a valid email address."
]
}
],
"data": []
}
And I want to parse it in a way where I can get all the items in "errors" no matter the name of the error or value. Because the objects inside "errors" aren't always going to be "name" and "email" there might be different ones, but they will always be structured like that.
I managed to get this far:
var theObject = (JObject)JsonConvert.DeserializeObject(theJsonString);
And the goal would be to make it into a dictionary where I could get the name and the value of the error. Or just the name and value as one string would also work.
Essentially getting a collection of all the errors.
UPDATE
I tried deserializing it into it's own object
var theObject = JsonConvert.DeserializeObject<ResponseObject>(responseString);
Where the model looks like this
public class ResponseObject
{
[JsonProperty("success")]
public bool Success { get; set; }
//[JsonProperty("errors")]
//public Error[] Errors { get; set; }
[JsonProperty("errors")]
public Dictionary<string, List<string>> errors { get; set; }
[JsonProperty("data")]
public object[] Data { get; set; }
}
Which then throws this error
{"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'System.Collections.Generic.Dictionary2[System.String,System.Collections.Generic.List1[System.String]]'
because the type requires a JSON object (e.g. {"name":"value"}) to
deserialize correctly.\r\nTo 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.\r\nPath 'errors', line 1,
position 27."}
Errors is a List<Dictionary<string, List<string>>>
It looks like this:
"errors": [ <--
{
"1": [
"Username "admin" has already been taken."
],
"2": [
"Email is not a valid email address."
]
}
] <--
,
not a Dictionary<string, List<string>> that will llok like :
"errors":
{
"1": [
"Username "admin" has already been taken."
],
"2": [
"Email is not a valid email address."
]
},
A easy solutution for you would be:
If u have Visual Studio open it.
Copy ur Json Code.
Click on this and it generate your Code automatically for you :)
click here
Edit -> Import Json
Good Luck! :)
Sometimes it can be happen that he choose a "false" Datatype, but on ur litte json u will be fine.
This would be the output:
public class Rootobject
{
public bool success { get; set; }
public Error[] errors { get; set; }
public object[] data { get; set; }
}
public class Error
{
public string[] name { get; set; }
public string[] email { get; set; }
}

Json as String inside another Json using SimpleJson c#

I need to parse the following Json
{
"type": "send",
"data": "{"window":"true", "shell":"true", "wait":"false"}",
"tag": ""
}
I want data to be interpreted as a simple string:
"{"window":"true", "shell":"true", "wait":"false"}"
not as a json inside a json. How sholud I escape it?
{
"type": "send",
"data": '{"window":"true", "shell":"true", "wait":"false"}',
"tag": ""
}
The corresponding class generated by json2csharp
public class RootObject
{
public string type { get; set; }
public string data { get; set; }
public string tag { get; set; }
}
Solved it. The easiest thing to do is generate the json with simple json instead of doing it by hand.

Parse Json Array with different of keyvalue

In one of my project i want to parse a JSON array with different key name. For Example
{ "details": [
{ "state": "myState1",
"place": [
{ "name": "placeName" } ] },
{ "state": "myState2",
"place": [
{ "name1": "placeName" } ] },
{ "state": "myState3",
"place": [
{ "name2": "placeName" } ] } }
So in this JSON please look at the place array. each time key like name1,name2,name3...,
.And also it is not necessary to get the same JSON at all the time. In some time only state1 or state1 and state3 and in some time state1 to state 50.
So how can i identify and parse exact data from this array
First of all your JSON is not well-formatted. You miss a closing square bracket ] before the last closing curly bracket }.
Then, you can't parse variable-name properties to a static class, but you can turn them into a dictionary. Here's an example of mapping classes that work with variable places:
public class Details
{
public string state { get; set; }
public List<Dictionary<string, string>> place { get; set; }
}
public class Wrap
{
public Details[] details { get; set; }
}
static void Main(string[] args)
{
string txt = File.ReadAllText("MyJSONFile.txt");
JavaScriptSerializer ser = new JavaScriptSerializer();
var data = ser.Deserialize<Wrap>(txt);
}
If also the place property will change name, I think the simplest way to parse it is to use the following, very loosely typed, class:
public class Wrap
{
public List<Dictionary<string,object>> details { get; set; }
}
where the object in the dictionary will be a string or a dictionary of properties according to the values in the JSON.

Categories

Resources