I am struggling with a subject that has a lot of variants in this forum but I can't seem to find one that suits me, and I think it's because of the way that my JSON array is :( I'm not an expert but I already manage to "almost" get the end.. I need to get hand in "Status" and "listOfCredDetails" value.
My JSON (is called responseFromServer):
{
"Status": {
"StatusCode":143,
"SubStatus":0,
"Description":"Ok"
},
"ListofCredDetails":
[{
"Client":"a",
"CredID":111,
"CredUserID":"abc"
},
{
"Client":"b",
"CredID":112,
"CredUserID":"def"
},
{
"Client":"c",
"CredID":113,
"CredUserID":"ghi"
}]
}
Then, based on lot of examples in this forum, taking bits and pieces I created my classes:
[Serializable]
public class StatusReturn
{
public int StatusCode { get; set; }
public int SubStatus { get; set; }
public string Description { get; set; }
}
[Serializable]
public class CredDetailsReturn
{
public string Client{ get; set; }
public int CredID{ get; set; }
public string CredUserID{ get; set; }
}
[Serializable]
public class GetUserCredentialDetailsReturn
{
public StatusReturn status;
public List<CredDetailsReturn> listOfCredDetails;
public GetUserCredentialDetailsReturn()
{
status = new StatusReturn();
listOfCredDetails = new List<CredDetailsReturn>();
}
}
Then Am going to deserialize to get
1."Status" and its elements into one object and
2."ListofCredDetails" and its List of elements into one object
and then creating object for "GetUserCredentialDetailsReturn" to return both status(object) and ListofCredDetails(object) at a time.
Can anyone help me understand how can i achieve this i have tried some like below to deserialize and to get Json data into two seperate objects.
But it is not working....
public GetUserCredentialDetailsReturn InvokeRequest(RESTInvokeClass objInvoke)
{
...
...
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string responseText = streamReader.ReadToEnd();
GetUserCredentialDetailsReturn result = new GetUserCredentialDetailsReturn();
result.status = JsonConvert.DeserializeObject<StatusReturn>(responseText);
result.listOfCredDetails = JsonConvert.DeserializeObject<List<CredDetailsReturn>>(responseText);
return result;
}
}
You need to first change your property names in the class GetUserCredentialDetailsReturnas status to Status and listOfCredDetails to ListofCredDetails.
Then you can try to de-serialize your Json into your class GetUserCredentialDetailsReturnby the code below.
GetUserCredentialDetailsReturn result = new GetUserCredentialDetailsReturn();
result = JsonConvert.DeserializeObject<GetUserCredentialDetailsReturn>(responseText);
You can get your status and listOfCredDetails with in the result.
// result.Status
// result.ListofCredDetails
Hope this will be helpful to you.
[Serializable]
public class GetUserCredentialDetailsReturn
{
public StatusReturn status { get; set; }
public List<CredDetailsReturn> listOfCredDetails { get; set; }
}
JsonConvert.Deserialize<GetUserCredentialDetailsReturn>(json_string)
If you need just some isolated elements of a (say very large) JSON File you need the lower level parts of the JSON Library, for example from Newtonsoft:
using Newtonsoft.Json;
Then create a parser which reads through the JSON Tokens:
var reader = new JsonTextReader(...);
You'll get token by token:
private void nextToken()
{
do
{
if (!reader.Read()) this.importError("unexpected end of file");
}
while (reader.TokenType == JsonToken.Comment);
}
and have to handle this in a Token Parser. For example if you read an array:
private void readMyArray()
{
// StartArray
if (reader.TokenType != JsonToken.StartArray) this.importError("expected start of array '['");
this.nextToken();
while (reader.TokenType != JsonToken.EndArray)
{
this.readMyElement();
}
// EndArray
if (reader.TokenType != JsonToken.EndArray) this.importError("expected end of array ']'");
this.nextToken();
}
This technique is explained in every book about building compilers.
Related
I have looked at several solutions over the web on reading nested json files but I haven't found one suitable to my need. Maybe because I am new to JSON. Here is my issue:
I have the following JSON in a file:
{
"ConfigError" : {
"DateSent": "2022-04-28T14:03:16.6628493-07:00",
"ToolType": "WSM",
"IsSent": true
},
"FileCopyError" : {
"DateSent": "2022-06-14T14:03:16.6628493-07:00",
"ToolType": "RMT",
"IsSent": false
}
}
For this I have written two classes. One for the Inner object:
public class SummaryEmailStatus
{
public DateTime DateSent { get; set; }
public string ToolType { get; set; }
public bool IsSent { get; set; }
}
One for the Outer Objects:
public class SummaryEmailClass
{
SummaryEmailStatus Status { get; set; } = new SummaryEmailStatus();
}
I would like to be able to read the JSON in C#. I'm primarily concerned with the inner objects. They are of same class but they need to be used differently. So ideally I'd want a function that I can pass in "ConfigError" or "FileCopyError" into and it will return SummaryEmailStatus class object populated by the values in the JSON:
public static void ReadJasonFile(string jsonFileName, string objctName)
{
List<SummaryEmailClass> emailClassList = new List<SummaryEmailClass>();
dynamic jsonFile = JsonConvert.DeserializeObject(File.ReadAllText(jsonFileName));
SummaryEmailStatus sumclass = jsonFile[objctName];
}
But this gives me a run time error saying:
Cannot implicitly convert type "Newtonsoft.Json.Linq.JObject to SummaryEmailStatus
How can I successfully parse out the inner summaryemailstatus objects?
Additionally, I'd like to be able to create the JSON data within C#. The reason being, when I read the JSON, I will do some task and then will need to update the values of the JSON with the current timestamps. I'd imagine, I'd need to rewrite the file. How can I write a nested JSON like this in C#?
If JSON is not the best way to do this, I am open to alternatives
you can try
string json = File.ReadAllText(jsonFileName);
Dictionary<string,SummaryEmailStatus> summaryEmailStatus =
JsonConvert.DeserializeObject<Dictionary<string,SummaryEmailStatus>>(json);
you can use it
SummaryEmailStatus configError = summaryEmailStatus["ConfigError"];
if you want update data
summaryEmailStatus["ConfigError"].DateSent= DateTime.Now;
and serialize back
json = JsonConvert.SerializeObject(summaryEmailStatus);
or if you have only 2 main properties, create a class
public class SummaryEmailClass
{
SummaryEmailStatus ConfigError { get; set; }
SummaryEmailStatus FileCopyError{ get; set; }
}
and use it
SummaryEmailClass summaryEmailStatus =
JsonConvert.DeserializeObject<SummaryEmailStatusClass>(json);
SummaryEmailStatus configError = summaryEmailStatus.ConfigError;
Summary
You need to convert your JObject into the type you are expecting, as shown here:
SummaryEmailStatus sumclass = jsonFile[objctName].ToObject<SummaryEmailStatus>();
Details
jsonFile[objtName] is of type JObject. The reason is because JsonConvert.DeserializeObject has no idea that you intend to convert that into a list of SummaryEmailStatus.
Once you have your array of JObjects, you can convert that into a SummaryEmailStatus as shown in the following snippet:
public static void ReadJasonFile(string jsonFileName, string objctName)
{
List<SummaryEmailClass> emailClassList = new List<SummaryEmailClass>();
dynamic jsonFile = JsonConvert.DeserializeObject(File.ReadAllText(jsonFileName));
SummaryEmailStatus sumclass = jsonFile[objctName].ToObject<SummaryEmailStatus>();
}
Easy way is kept both objects in JSON, I rewrite your code and add root. For example, if you want to write Config Error and don't write File Copy Error, you can save one of them like null.
public class ConfigError
{
public DateTime DateSent { get; set; }
public string ToolType { get; set; }
public bool IsSent { get; set; }
}
public class FileCopyError
{
public DateTime DateSent { get; set; }
public string ToolType { get; set; }
public bool IsSent { get; set; }
}
public class Root
{
public ConfigError ConfigError { get; set; }
public FileCopyError FileCopyError { get; set; }
}
//in your method to get all data
var json = File.ReadAllText(jsonFileName);
var myDeserializedClass = JsonConvert.DeserializeObject<Root>(json);
Example change config and write to file
var json = #"{
""ConfigError"" : {
""DateSent"": ""2022-04-28T14:03:16.6628493-07:00"",
""ToolType"": ""WSM"",
""IsSent"": true
},
""FileCopyError"" : {
""DateSent"": ""2022-06-14T14:03:16.6628493-07:00"",
""ToolType"": ""RMT"",
""IsSent"": false
}
}";
var conf = JsonConvert.DeserializeObject<Root>(json);
conf.ConfigError.DateSent = DateTime.Now;
conf.ConfigError.ToolType = "New way";
conf.ConfigError.IsSent = false;
conf.FileCopyError = null;
var newJson = JsonConvert.SerializeObject(conf);
File.WriteAllText("your path", newJson);
Does Newtonsoft.JSON library have a simple way I can automatically deserialize JSON into 2 different Models/classes?
For example I get the JSON:
[{
"guardian_id": "1453",
"guardian_name": "Foo Bar",
"patient_id": "938",
"patient_name": "Foo Bar",
}]
And I need de-serialize this to the following models:
class Guardian {
[JsonProperty(PropertyName = "guardian_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "guardian_name")]
public int Name { get; set; }
}
class Patient {
[JsonProperty(PropertyName = "patient_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "patient_name")]
public int Name { get; set; }
}
Is there a simple way to deserialize this JSON into 2 Models without having to iterate over the JSON? Maybe JSON property ids will just work?
Pair<Guardian, Patient> pair = JsonConvert.DeserializeObject(response.Content);
First off, your models are slightly incorrect. The name properties need to be strings, instead of integers:
class Guardian
{
[JsonProperty(PropertyName = "guardian_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "guardian_name")]
public string Name { get; set; } // <-- This
}
class Patient
{
[JsonProperty(PropertyName = "patient_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "patient_name")]
public string Name { get; set; } // <-- This
}
Once you've corrected that, you can deserialize the JSON string into two lists of different types. In your case, List<Guardian> and List<Patient> respectively:
string json = #"[{'guardian_id':'1453','guardian_name':'Foo Bar','patient_id':'938','patient_name':'Foo Bar'}]";
var guardians = JsonConvert.DeserializeObject<List<Guardian>>(json);
var patients = JsonConvert.DeserializeObject<List<Patient>>(json);
It you want to do it with 1 call, you need to create a class that matches the JSON. That class can then return Guardian and Patient objects as needed. Also you'll need to use an array or list for the return type because the source JSON is an array.
The class to create:
public class Pair
{
public Pair()
{
Guardian = new Guardian();
Patient = new Patient();
}
[JsonIgnore]
public Guardian Guardian { get; set; }
[JsonIgnore]
public Patient Patient { get; set; }
[JsonProperty(PropertyName = "guardian_id")]
public int GuardianID
{
get { return Guardian.ID; }
set { Guardian.ID = value; }
}
[JsonProperty(PropertyName = "guardian_name")]
public string GuardianName
{
get { return Guardian.Name; }
set { Guardian.Name = value; }
}
[JsonProperty(PropertyName = "patient_id")]
public int PatientID
{
get { return Patient.ID; }
set { Patient.ID = value; }
}
[JsonProperty(PropertyName = "patient_name")]
public string PatientName
{
get { return Patient.Name; }
set { Patient.Name = value; }
}
}
And how to use it:
var pairs = JsonConvert.DeserializeObject<Pair[]>(response.Content);
if (pairs.Any())
{
var pair = pairs[0];
Console.WriteLine(pair.Guardian.Name);
Console.WriteLine(pair.Patient.Name);
}
Not in one call, and it seems the data is an array, so you need a little more work.
Zip is the key method here to join the two separate object lists:
Guardian[] guardians = JsonConvert.DeserializeObject<Guardian[]>(response.Content);
Patient[] patients = JsonConvert.DeserializeObject<Patient[]>(response.Content);
var combined = guardians.Zip(patients, (g, p) => Tuple.Create(g, p)).ToList();
It would be far more easier to just read the JSON at once, it a single object.
It can't be done with 1 call with the types that you show. You can try using the generic <T> approach for each type, also you'll need to use arrays or lists for the return type because the source JSON is an array:
var guardians = JsonConvert.DeserializeObject<Guardian[]>(response.Content);
var patients = JsonConvert.DeserializeObject<Patient[]>(response.Content);
And then combine the two if you need them to be paired. E.g. if you are sure that you always have just one of each:
var pair = new Pair(guardians[0], patients[0]);
You could make a type to house the two subobjects:
[JsonConverter(typeof(GuardianPatientConverter))]
class GuardianPatient
{
public Guardian Guardian { get; set; }
public Patient Patient { get; set; }
}
And then create a JSON converter to handle the JSON:
class GuardianPatientConverter : JsonConverter
{
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return typeof(GuardianPatient) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
var jObject = JObject.Load(reader);
var guardian = new Guardian();
var patient = new Patient();
serializer.Populate(jObject.CreateReader(), guardian);
serializer.Populate(jObject.CreateReader(), patient);
return new GuardianPatient()
{
Guardian = guardian,
Patient = patient
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
And then you can use it like so:
var json = "[{\"guardian_id\":\"1453\",\"guardian_name\":\"Foo Bar\",\"patient_id\":\"938\",\"patient_name\":\"Foo Bar\",}]";
var objects = JsonConvert.DeserializeObject<IEnumerable<GuardianPatient>>(json);
and if you want it as an array of pairs:
var objects = JsonConvert.DeserializeObject<IEnumerable<GuardianPatient>>(json)
.Select(o => new Pair(o.Guardian, o.Patient))
.ToArray();
This won't make it any faster, but I suspect you're looking for an easier way to work with the JSON.
One another approach would be creating class that matches JSON format, i.e. class with four properties with corresponding names. Then, deserialize JSON into that class and then use it in your code (set properties of objects with values from JSON, pass deserialized object to constructor of another class).
In your models, The name properties need to be strings, instead of integers. After correcting it.
You can use Tuple class
string json = #"[{'guardian_id':'1453','guardian_name':'Foo Bar','patient_id':'938','patient_name':'Foo Bar'}]";
var combination = new Tuple<List<Guardian>, List<Patient>>(JsonConvert.DeserializeObject<List<Guardian>>(json), JsonConvert.DeserializeObject<List<Patient>>(json));
static void Main(string[] args)
{
string json = JsonConvert.SerializeObject(new[]
{
new
{
guardian_id = "1453",
guardian_name = "Foo Bar",
patient_id = "938",
patient_name = "Bar Foo",
}
});
Guardian[] guardians = JsonConvert.DeserializeObject<Guardian[]>(json);
Patient[] patients = JsonConvert.DeserializeObject<Patient[]>(json);
}
Since both your objects are the same, wouldn't it make more sense to just have an ID/Name structure of a single base class? If you need to send all the data at the same time, you can restructure your data and use a data transfer object pattern. The JSON object would become
[{
"guardian": {
"id": "1453",
"name": "Foo Bar"
},
"patient": {
"id" : "938",
"name": "Foo Bar"
}
}]
And your corresponding data objects would be:
public class Record {
public int id { get; set; } // or string. I'm not sure which would be more appropriate
public string name { get; set;}
}
and
public class RecordDto {
public Record guardian { get; set; }
public Record patient { get; set; }
}
And your API would receive a
List<RecordDto>
parameter (since you are passing an array of objects).
I have looked over example after example after example and none of my attempts have worked.
I'm attempting to deserialize this JSON return:
{
"status": "success",
"data": {
"result": "match",
"id_user": 26564,
"dob_match": null,
"first_name_match": null,
"last_name_match": null
},
"code": 200
}
Here is my JSON object class declaration:
[DataContract]
internal class DccCoachApi
{
[DataMember]
public string result { get; set; }
public string id_user { get; set; }
public string dob_match { get; set; }
public string first_name_match { get; set; }
public string last_name_match { get; set; }
}
In my stream method, my streamRead variable is filled with:
{"status":"success","data":{"result":"match","id_user":26564,"dob_match":null,"first_name_match":null,"last_name_match":null},"code":200}
Method 1 does not populate coachId:
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(streamRead)))
{
// Deserialization from JSON
var deserializer = new DataContractJsonSerializer(typeof(DccCoachApi));
var dccObj = (DccCoachApi)deserializer.ReadObject(ms);
coachId = dccObj.id_user;
}
Nor does method 2:
DccCoachApi coach = new JavaScriptSerializer().Deserialize<DccCoachApi>(streamRead);
coachId = coach.id_user;
nor does method 3:
JavaScriptSerializer js = new JavaScriptSerializer();
DccCoachApi dccObj = js.Deserialize<DccCoachApi>(streamRead);
coachId = dccObj.id_user;
nor does method 4:
dynamic dccObject = js.Deserialize<dynamic>(streamRead);
coachId = dccObject["id_user"];
The hard error that gets produced when i pull the value directly off method 4 is:
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
Methods 1-3 do not hit a hard error, however they populate coachId with no data.
Can somebody please let me know what i'm doing wrong?
You can simply generate proper classes here: http://json2csharp.com/
This is how it should look like you don't need the DataMember Attributes, it might confuse the serializer to only de-serialize this single property:
public class Data
{
public string result { get; set; }
public int id_user { get; set; }
public object dob_match { get; set; }
public object first_name_match { get; set; }
public object last_name_match { get; set; }
}
public class RootObject
{
public string status { get; set; }
public Data data { get; set; }
public int code { get; set; }
}
Code:
var deserializer = DataContractJsonSerializer(typeof(RootObject));
var root = (RootObject)deserializer.ReadObject(ms);
var coachId = root.data.id_user;
I revised the code to look like this, and it is dumping my value perfectly. Thanks much to everyone who helped me reach the solution. Plutonix, thanks as well for the paste special 411. I had no idea that existed. VERY useful!
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
var streamRead = reader.ReadToEnd();
reader.Close();
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(streamRead)))
{
JavaScriptSerializer js = new JavaScriptSerializer();
DccCoachRootobject dccObj = js.Deserialize<DccCoachRootobject>(streamRead);
coachId = dccObj.data.id_user.ToString();
}
}
i'm working with Vk.com api, in particular with this json string:
{
"response":
[338775,
{"aid":108787020,
"owner_id":2373452,
"artist":" Moby",
"title":"Flowers",
"duration":208,
"url":"https:\/\/cs1-50v4.vk-cdn.net\/p3\/c762273870cc49.mp3?extra=t9I-RMkSlAHkhe8JtOUUZBTZqkFVE9MJ_Q-TPmOhxPHTfHazQWEYBf4LqrOY64xLX9AuzaKwvLo4PECSFiHyWM53WMDWVcBAZVT5jlIbZ9X8ag","lyrics_id":"6060508",
"genre":22}
]
}
I have a class for parsing data:
public class AlbumResponse
{
[JsonProperty("artist")]
public string artist { get; set; }
[JsonProperty("title")]
public string title { get; set; }
[JsonProperty("duration")]
public string duration { get; set; }
[JsonProperty("url")]
public string url { get; set; }
}
And List for deserialization:
public class VkAlbum
{
public List<AlbumResponse> response { get; set; }
}
Than I use
var album = JsonConvert.DeserializeObject<VkAlbum>(responseText);
BUT it doesn't work (A first chance exception of type 'Newtonsoft.Json.JsonSerializationException') because of "338775" after "response".
So how can I deserialize it without using
public List<object> response { get; set; }
instead of my AlbumResponse class?
A primitive JSON sanitation for your disposal. Not the most elegant code, but i'm sure you can take it from here.
responseText = Regex.Replace(responseText, "[\t|\r\n]", "");
if (responseText.IndexOf("response\": [") != -1)
{
int start = responseText.IndexOf('[') + 1;
int end = responseText.IndexOf(',', start);
responseText = responseText.Substring(0, start) + responseText.Substring(end + 1);
}
var album = JsonConvert.DeserializeObject<VkAlbum>(responseText);
technically json response is not equivalent to C# List<AlbumResponse>. JSON array allows mixed types so essentially it can contains numbers and other nested objects, in your case AlbumResponse.
you can avoid exception by using List<object> and checking it's first element if it's number, if it is, ignore or do whatever you want to do and typecast 2nd element in list to AlbumResponse.
e.g.
var res = response [1] as AlbumResponse;
if(res!=null)
{
// do something interesting...
I am learning for the first time how to get a json file from a third party vendor and I am trying to do such with steam. I am trying to retrieve game name and play time of a specific game for a specific user. Based on the online documentation I have read the following code should be working, but the problem is that I am getting back a null. If I take the generated URL and put it in the browser I get back results which means my URL is good, but the way I am parsing it is wrong.
public class SteamMemberViewModel
{
public List<SteamGameViewModel> games { get; set; }
}
public class SteamGameViewModel
{
public int appid { get; set; }
public string name { get; set; }
public int playtime_forever { get; set; }
}
private string GetSteamGame()
{
const int rocketLeagueId = 252950;
var format = string.Format("http://api.steampowered.com/{0}/{1}/v{2}/?key={3}&steamid={4}&include_appinfo=1&format=json", "IPlayerService", "GetOwnedGames", "0001", "ABC", "123");
using (WebClient wc = new WebClient())
{
var json = JsonConvert.DeserializeObject<SteamMemberViewModel>(wc.DownloadString(format));
var rocketLeage = json.games.Where(g => g.appid == rocketLeagueId);
var steamGameViewModels = rocketLeage as SteamGameViewModel[] ?? rocketLeage.ToArray();
if (steamGameViewModels.Count() == 1)
{
var playtime = steamGameViewModels.First().playtime_forever;
return steamGameViewModels.First().name + " - " + playtime;
}
}
return "Steam Game Not Found";
}
The error that I Get is
Value cannot be null.
Parameter name: source
Line 26: var json = JsonConvert.DeserializeObject(wc.DownloadString(format));
Line 27:
Line 28: var rocketLeage = json.games.Where(g => g.appid == rocketLeagueId);
Line 29: var steamGameViewModels = rocketLeage as SteamGameViewModel[] ?? rocketLeage.ToArray();
Line 30: if (steamGameViewModels.Count() == 1)
Source File: e:_websites\Local\Projects\Azularis\Azularis.System.Events\Azularis.System.Events\Controllers\HomeController.cs Line: 28
EDIT:
I have also tried running the code as follows:
var result = wc.DownloadString(format);
var data = JsonConvert.DeserializeObject<SteamMemberViewModel>(result);
var count = data.games.Count();
return count.ToString();
And I still got the same error. result comes back with values though.
JSON FILE EXAMPLE:
{
"response": {
"game_count": 16,
"games": [
{
"appid": 10,
"name": "Counter-Strike",
"playtime_forever": 5019,
"img_icon_url": "6b0312cda02f5f777efa2f3318c307ff9acafbb5",
"img_logo_url": "af890f848dd606ac2fd4415de3c3f5e7a66fcb9f",
"has_community_visible_stats": true
}
]
}
}
Value games inside SteamMemberViewModel is always null.
I would think your issue is that your top object in the JSON is response but you are trying to parse that into the equivalent of the games array. I would think you need to get the array object and then parse so you need to go down a level into the JSON object.
I can't be sure as you do not know if that serializer is performing some recursive work until it finds the object (I doubt it though) but the docs does not seem to do so:
http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm
in the example, it clearly states you need to get down to the object you mean to be your top level. And it is not response in your example.
So you'd have to do something like (pseudo-code):
JObject json = JObject.Parse(jsonString);
IList<JToken> array = json["response"]["games"].Children().ToList();
if(array != null)
{
var data = JsonConvert.DeserializeObject<SteamMemberViewModel>(array.ToString());
}
I know you already have an accepted answer. Your issue is easily fixable. Replace SteamMemberViewModel code with below code.
public class SteamMemberViewModel
{
public Response response { get; set; }
}
public class Response
{
public int game_count { get; set; }
public Game[] games { get; set; }
}
public class Game
{
public int appid { get; set; }
public string name { get; set; }
public int playtime_forever { get; set; }
public string img_icon_url { get; set; }
public string img_logo_url { get; set; }
public bool has_community_visible_stats { get; set; }
}