Deserialize from a specific level in C# - c#

I retrieve an information from Steam about a specific game. I provide an application url: http://store.steampowered.com/app/57690/ and get a JSON response like:
{
"57690":{ // this is dynamically got from application id above ^
"success":true
"data": { }
}
}
I have an object, SteamData
public bool success { get; set; }
public InternalData data { get; set; }
and InternalData
public string name { get; set; }
public string about_the_game { get; set; }
public string supported_languages { get; set; }
...
I tried to deserialize above json to SteamData using:
SteamData data = JsonConvert.DeserializeObject<SteamData>( thatJsonAbove );
It's not working because there exists a root which is an application id...
How to deserialize only what is inside root (in this example, what's inside "57690") ?

In case of using Newtonsoft JSON library you may try this:
JObject gameInfo = JObject.Parse(json);
SteamData data= gameInfo.SelectToken("57690", false).ToObject<SteamData>();
Since you know game's id - you can easily use this approach.

Related

Json with data inconsistency

I got this strange API response from one external service:
{emplooye: "Michael",age:"25",attachments:[{idAttachment: "23",attachmentPath:"C://Users/1"},{idAttachment: "24",attachmentPath:"C://Users/2"}]},{emplooye: "John",age:"30",attachments:{idAttachment: "25",attachmentPath:"C://Users/3"}}
Has anyone ever faced a situation where sometimes the "Attachment" property can be an array, sometimes it can be an object? I created a class to manipulate the data, but when I find an object, the code breaks.
I'm doing this in C#.
Class Used
public class Attachments
{
public string idAttachment{ get; set; }
public string attachmentPath{ get; set; }
}
public class Root
{
public string emplooye {get; set;}
public string age {get;set}
public List<Attachments> attachments { get; set; } = new List<Attachments>();
}
your json is not even close to json, should be something like this
var json = "[{\"emplooye\":\"Michael\",\"age\":\"25\",\"attachments\":[{\"idAttachment\":\"23\",\"attachmentPath\":\"C://Users/1\"},{\"idAttachment\":\"24\",\"attachmentPath\":\"C://Users/2\"}]},{\"emplooye\":\"John\",\"age\":\"30\",\"attachments\":{\"idAttachment\":\"25\",\"attachmentPath\":\"C://Users/3\"}}]";
Using Newtonsoft.Json you can create a JsonConstructor
using Newtonsoft.Json;
List<Data> data= JsonConvert.DeserializeObject<List<Data>>(json);
public class Data
{
public string emplooye { get; set; }
public string age { get; set; }
public List<Attachments> attachments { get; set; }
[JsonConstructor]
public Data(JToken attachments)
{
if (attachments.Type.ToString() == "Array")
this.attachments = attachments.ToObject<List<Attachments>>();
else
this.attachments = new List<Attachments> { attachments.ToObject<Attachments>() };
}
public Data() {}
}
public class Attachments
{
public string idAttachment { get; set; }
public string attachmentPath { get; set; }
}
You can use Newtonsoft to parse to a JToken which will handle the typing for you, but with the downside of not having a stable and predictable class to deserialize to automatically
Then, you would want to check its type, which returns a JTokenType enum
Once you know what the underlying types are, marshal the data into your DTO classes
JToken responseJT = JToken.Parse(json); //json string
if (responseJT.Type == JTokenType.Array)
//its an array, handle as needed ...
else if (responseJT.Type == JTokenType.Object)
//its an object, handle as needed ...
Personally, I would keep the attachments property as a List<Attachments> and if the JToken has a JSON object I would just set it as the [0] index of that property. This way things stay consistent and you can use LINQ on that property with ease

Unable to use JSON data with Newtonsoft.Json in WPF

I am retrieving data from office365 api. The response is in JSON format. I want to get data like Id, DisplayName etc. into variables but not getting the right way to do it. Following this link. I'm new to API and JSON. Will Appreciate pointers as well towards best learning links.Sample JSON below for listing sub folders of Inbox folder.
Response JSON data.
{"#odata.context":"https://outlook.office365.com/api/v1.0/$metadata#Me/Folders('Inbox')/ChildFolders","value":
[
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmsdfsdfdDSFSDFDFDF=')",
"Id":"AAMkADBjMdfgdfgDFGDFGDFGdfGDFGDFGDFGGDzrACAAB4xqMmAAA=",
"DisplayName":"SampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":8,"TotalItemCount":94},
{"#odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user#demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEasdasdasdASDASDASDASDSADDASDASDAB4xqMnAAA=')",
"Id":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmOGZkNGRhZmIzNQAuAasdASDASDASDASEDASDASDxSEHjzrACAAB4xqMnAAA=",
"DisplayName":"AnotherSampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":21,"TotalItemCount":75}
]
}
The C# code using to parse JSON and find the required data.
HttpResponseMessage response = httpClient.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
throw new WebException(response.StatusCode.ToString() + ": " + response.ReasonPhrase);
string content = response.Content.ReadAsStringAsync().Result;
JObject jResult = JObject.Parse(content);
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
var folderName = results.Id;
var folderId = results.Name;
//Attempt two - [Not working - Throwing exception -
//Object reference not set to an instance of an object.]
var folderID = (string)jResult["odata.context"]["odata.id"][0]["Id"];
First create a class for your json object
public class RootObject
{
[JsonProperty(PropertyName = "#odata.context")]
public string context { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
[JsonProperty(PropertyName = "#odata.id")]
public string dataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Then Json Convert the Json string to your RootObject if your are using Newtonsoft Json then Deserilaze by using
RootObject shortiee = JsonConvert.DeserializeObject<RootObject>("Your Json String");
private List<string> GetDisplayNames(JObject content)
{
var obj = Json.Parse(content);
var values = obj["value"].ToList();
var displayNames = new List<string>();
foreach (var value in values)
{
displayNames .Add(system["DisplayName"].ToString());
}
return displayNames;
}
This would return the names, for example, and you could do this for each value you need to retrieve. However, this does not require you to serialize/deserialize the json object before using it. It works, but is most likely not best practice.
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
Side note: There is no key called "odata.error" in your JSON data. So you're effectively calling something which will return null.
One of the ways to deserialise JSON is to create model classes for the objects you want to process and deserialise into them directly, eg. JsonConvert.DeserializeObject<Folder>(content). As you are talking to an Office365 API, you find documentation and examples here on how they are defined.
Taken your folder response as an example, your model for a single Folder could look like this:
public class Folder
{
[JsonProperty(PropertyName = "#odata.id")]
public string OdataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
Note1: in your example, you get a response with list of folders, so have to adjust this accordingly.
Note2: you can use JsonProperty to define a mapping between a JSON property/key and a C# property as shwon for #odata.id.
However, you can also use the Outlook Client Library which would make it mostly unnecessary to deal with JSON data directly (which seems preferable, unless you have a very specific reason to deal with JSON directly).

How Can I Deserialize JSON Data Using C#?

I have seen some other questions like this, but those are quite complex JSON data's that have objects within objects. Although the JSON I'm working with is never static, I doubt it's as complex as those. Also, it's my first time using JSON with C# so I'm a little clueless.
What I'm trying to achieve is to separate the data that is received from an API that I prompt using WebRequest in C#.
{
"johhny.debt": {
"id":35187540,
"name":"johnny.debt",
"profileIconId":786,
"Level":30,
"revisionDate":1428019045000
}
}
The returned JSON data is in a fashion like thereof.
I want to be able to access all of the properties of the above string in the following manner:
ID :
Name:
~~
~~
~~
... and so forth.
I'm assuming some type of class has to be made for this?
All help is appreciated, thank you all in advance.
Install Json.Net from Nuget
Install-Package Newtonsoft.Json
https://www.nuget.org/packages/Newtonsoft.Json/
Declare class for inner object ({"id":..., "name": ... }):
public class InnerObject
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Username { get; set; }
[JsonProperty("profileIconId")]
public int ProfileIconId { get; set; }
[JsonProperty("level")]
public int Level { get; set; }
[JsonProperty("revisionDate")]
public string RevisionDate { get; set; }
}
As you can see you can specify rename mapping from json fields to .Net object properties using JsonPropertyAttribute.
Read your json to Dictionary<string,InnerObject> and get value of "johhny.debt" key:
var dict = JsonConvert.DeserializeObject<Dictionary<string, InnerObject>>(jsonText);
var johhny = dict["johhny.debt"];
Or if your need always to parse exact json property 'johhny.debt', you could create root object class:
public class RootObject
{
[JsonProperty("johhny.debt")]
public InnerObject JohhnyDept { get; set; }
}
And deserialize it:
var root = JsonConvert.DeserializeObject<RootObject>(jsonText);
var johhny = root.JohhnyDebt;
Just Create a class like this
public class RootObject
{
public int Id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int Level { get; set; }
public string revisionDate { get; set; }
}
then install json.Net and this code to your main method
var jsonObject=JsonConvert.DeserializeObject<RootObject>(jsonText);
That's all
Update
var obj = JObject.Parse(json);
var RootObject = new RootObject()
{
Id = (int)obj["johhny.debt"]["id"],
Level = (int)obj["johhny.debt"]["Level"],
name = (string)obj["johhny.debt"]["name"],
profileIconId = (int)obj["johhny.debt"]["profileIconId"],
revisionDate = (string)obj["johhny.debt"]["revisionDate"]
};

Reading a JSON file from web page and convert it in List<Object> in C#

I'm facing some problems with the read of a JSON file, which is this one:
{
"giocatori": [
{
"Giocatore": "124",
"Cognome": "DE SANCTIS",
"Ruolo": "P",
"Squadra": "ROM"
},
{
"Giocatore": "140",
"Cognome": "MIRANTE",
"Ruolo": "P",
"Squadra": "PAR"
},
{
"Giocatore": "156",
"Cognome": "SKORUPSKI",
"Ruolo": "P",
"Squadra": "ROM"
}
],
"success": 1
}
What I want to get from this PHP is an List, where the Player's class with this attributes;
public string Giocatore;
public string Cognome;
public string Ruolo;
public string Squadra;
I don't know why, but I face some problems with the Microsoft.Json library, in particular with Json.DeserializeObject> method, which is not able to read that web page. Can you provide some hint how to obtain a List in C# of Player ? Thank you so much for your support !
Go to http://json2csharp.com/, post your JSON there, and get the following classes:
public class Giocatori
{
public string Giocatore { get; set; }
public string Cognome { get; set; }
public string Ruolo { get; set; }
public string Squadra { get; set; }
}
public class RootObject
{
public List<Giocatori> giocatori { get; set; }
public int success { get; set; }
}
To deserialize your JSON string with JavaScriptSerializer, do:
var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(jsonString);
var list = root.giocatori;
To deserialize your JSON string with Json.NET, a widely used, free, open source JSON serializer, download and install it according to the instructions on the home page and do:
var root = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);
var list = root.giocatori;

C# convert string to dictionary

I get this response string from the Bitly api:
{ "status_code": 200,
"status_txt": "OK",
"data":
{ "long_url": "http:\/\/amazon.de\/",
"url": "http:\/\/amzn.to\/1mP2o58",
"hash": "1mP2o58",
"global_hash": "OjQAE",
"new_hash": 0
}
}
How do I convert this string to a dictionary and how do I access the value for the key "url" (without all the \)
This isn't just some ordinary string. This is a data structure in JSON format, a common and well-established format, originally used in Javascript but now rather common as a data transfer mechanism between services and clients.
Rather than reinventing the wheel and parsing the JSON yourself, I suggest you use an existing JSON library for C#, such as JSON.NET, which will eat up that string and parse it into .NET objects for you.
Here's a code sample, taken from JSON.NET's documentation, showing its usage:
string json = #"{
'href': '/account/login.aspx',
'target': '_blank'
}";
Dictionary<string, string> htmlAttributes =
JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Console.WriteLine(htmlAttributes["href"]);
// /account/login.aspx
Console.WriteLine(htmlAttributes["target"]);
// _blank
If you add a package like Newtonsoft's Json to your project, you can deserialize the Json in to an anonymous type. You can then fetch the url from that. This is available via NuGet within Visual Studio and provides support for async or sync serialization/deserialization.
public string GetUrl(string bitlyResponse)
{
var responseObject = new
{
data = new { url = string.Empty },
};
responseObject = JsonConvert.DeserializeAnonymousType(bitlyResponse, responseObject);
return responseObject.data.url;
}
I'd use JSON.NET.
http://james.newtonking.com/json
MIT License which means if you're doing anything commercial you are good.
I don't think you would want to go straight to a Dictionary, because there is some stuff there that isn't a one to one relationship. So you could make a class like the following.
public class BitlyData
{
public string LongUrl{ get; set; }
public string Url { get; set; }
public string Hash { get; set; }
public string GlobalHash { get; set; }
public string NewHash { get; set; }
}
You could then use Json.NET to turn that String into an JObject. So we'll call your string bitlyString.
JObject bitlyObject = JObject.Parse(bitlyString);
Now we have that all that is left to do is access the data.
BitlyData theData = JsonConvert.DeserializeObject<BitlyData>(bitlyObject["data"]);
Then you can access the url (and any other pieces) using the getters.
Of course you could make it even better by having class that handles the other bits as well so you just do one serialisation.
1)Add these classes to your project
public class Rootobject
{
public int status_code { get; set; }
public string status_txt { get; set; }
public Data data { get; set; }
}
public class Data
{
public string long_url { get; set; }
public string url { get; set; }
public string hash { get; set; }
public string global_hash { get; set; }
public int new_hash { get; set; }
}
2)Add a reference to JSON.NET
3)
string jsonString= "YOUR JSON STRING";
Rootobject weps = JsonConvert.DeserializeObject<Rootobject>(jsonString);
Console.WriteLine(weps.status_code);
if (weps.data != null)
{
Console.WriteLine(weps.data.url);
Console.WriteLine(weps.data.global_hash);
//...
}

Categories

Resources