Get multiples Arrays from dictionary Object - c#

I have a JSON call, this brings me an object with four Arrays.
HttpWebRequest apiRequest = WebRequest.Create(url) as HttpWebRequest;
string apiResponse = "";
using (HttpWebResponse response = apiRequest.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
apiResponse = reader.ReadToEnd();
}
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(apiResponse);
var results = dict["results"];
Then i use var dict to storage this four arrays, later i have var results to select an specific array. In this case, the array i want is "results".
var results "output":
The problem is i want access the data for each array, but i don't know how do this.
ArrayList list = (ArrayList)results;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < list.Count; i++)
{
if (builder.Length > 0)
{
builder.Append(", ");
}
object current = list[i];
builder.Append(current);
}
LblTitle.Text = builder.ToString();
I see this code in other post and i adapt to my code, but this only brings me this System.Collections.Generic.Dictionary'2[System.String,System.Object], for each array.
I want something like this
string[] arrayresult = builder.ToString();
string[] arrayresult2 = builder.ToString();
etc, for each array in the object results. And later access each array data like this LblTitle.Text = arrayresult[1]; LblTitle2.Text = arrayresult2[1];
Edit: Adding JSON Example
"{\"page\":1,\"results\":[{\"adult\":false,\"backdrop_path\":\"/7ABsaBkO1jA2psC8Hy4IDhkID4h.jpg\",\"genre_ids\":[28,12,14,878],\"id\":19995,\"original_language\":\"en\",\"original_title\":\"Avatar\",\"overview\":\"In the 22nd century, a paraplegic Marine is dispatched to the moon Pandora on a unique mission, but becomes torn between following orders and protecting an alien civilization.\",\"popularity\":1363.938,\"poster_path\":\"/jRXYjXNq0Cs2TcJjLkki24MLp7u.jpg\",\"release_date\":\"2009-12-10\",\"title\":\"Avatar\",\"video\":false,\"vote_average\":7.5,\"vote_count\":26216},{\"adult\":false,\"backdrop_path\":\"/198vrF8k7mfQ4FjDJsBmdQcaiyq.jpg\",\"genre_ids\":[878,28,12],\"id\":76600,\"original_language\":\"en\",\"original_title\":\"Avatar: The Way of Water\",\"overview\":\"Set more than a decade after the events of the first film, learn the story of the Sully family (Jake, Neytiri, and their kids), the trouble that follows them, the lengths they go to keep each other safe, the battles they fight to stay alive, and the tragedies they endure.\",\"popularity\":1000.602,\"poster_path\":\"/1yppMeTNQwDrzaUH4dRCx4mr8We.jpg\",\"release_date\":\"2022-12-14\",\"title\":\"Avatar: The Way of Water\",\"video\":false,\"vote_average\":0,\"vote_count\":0},{\"adult\":false,\"backdrop_path\":null,\"genre_ids\":[99],\"id\":287003,\"original_language\":\"en\",\"original_title\":\"Avatar: Scene Deconstruction\",\"overview\":\"The deconstruction of the Avatar scenes and sets\",\"popularity\":261.979,\"poster_path\":\"/uCreCQFReeF0RiIXkQypRYHwikx.jpg\",\"release_date\":\"2009-12-18\",\"title\":\"Avatar: Scene Deconstruction\",\"video\":false,\"vote_average\":9,\"vote_count\":3},{\"adult\":false,\"backdrop_path\":null,\"genre_ids\":[99],\"id\":111332,\"original_language\":\"en\",\"original_title\":\"Avatar: Creating the World of Pandora\",\"overview\":\"The Making-of James Cameron's Avatar. It shows interesting parts of the work on the set.\",\"popularity\":259.613,\"poster_path\":\"/d9oqcfeCyc3zmMal6eJbfj3gatc.jpg\",\"release_date\":\"2010-02-07\",\"title\":\"Avatar: Creating the World of Pandora\",\"video\":false,\"vote_average\":7,\"vote_count\":20}],\"total_pages\":3,\"total_results\":55}"
I convert this JSON to Class, thanks for the tip. This is my class now:
public class Result
{
public bool adult { get; set; }
public string backdrop_path { get; set; }
public List<int> genre_ids { get; set; }
public int id { get; set; }
public string original_language { get; set; }
public string original_title { get; set; }
public string overview { get; set; }
public double popularity { get; set; }
public string poster_path { get; set; }
public string release_date { get; set; }
public string title { get; set; }
public bool video { get; set; }
public double vote_average { get; set; }
public int vote_count { get; set; }
}
public class Root
{
public int page { get; set; }
public List<Result> results { get; set; }
public int total_pages { get; set; }
public int total_results { get; set; }
}

I would suggest you create a proper C# class to deserialize your JSON into. We can't see how you JSON looks, so I'll just give a simple example. Let's say this is your JSON:
{
"results": [
[
"foo",
"bar"
],
[
"baz",
"qux"
]
],
"someOtherField": "someValue"
}
If you go to https://json2csharp.com/ you can convert this into a C# class like this:
public class Root
{
public List<List<string>> results { get; set; }
public string someOtherField { get; set; }
}
To deserialize and access the data, you simply do the following (I'm using System.Text.Json instead of JavaScriptSerializer - see comment below):
var root = JsonSerializer.Deserialize<Root>(apiResponse);
// ...
List<string> listResult = root.results[0];
List<string> listResult2 = root.results[1];
// ...
LblTitle.Text = listResult[1]; // "bar"
LblTitle2.Text = listResult2[1]; // "qux"
Please refer to the definition of JavaScriptSerializer:
For .NET Framework 4.7.2 and later versions, use the APIs in the System.Text.Json namespace for serialization and deserialization. For earlier versions of .NET Framework, use Newtonsoft.Json.
See here for how to use System.Text.Json .
If you want to use Newtonsoft.Json instead, you should replace JsonSerializer.Deserialize with JsonConvert.DeserializeObject:
var root = JsonConvert.DeserializeObject<Root>(apiResponse);

Related

C# Non-standard JSON parsing

I have an oddly formulated JSON response string in this format:
{
"Result": <this is the array of Ticket objects>,
"IsLastPage": true,
"NextSkip": 1,
"NextTake": 1,
"PageCount": 2,
"TotalCount": 3,
"QueryResultHash": "sample string 4"
}
Usually I would access the Json array (the Result value above) when the array is the only thing being returned, like so:
var jsonArray = JArray.Parse(resultString);
foreach (var jsonObject in jsonArray)
{ ... }
But I am not sure how to break down the above string so that I can get the 7 values individually and parse the array. Any suggestions?
If possible, I would use the library Newtonsoft.Json (https://www.nuget.org/packages/Newtonsoft.Json/).
Then you can create a ResponseContainer class. Something like,
//generated by http://json2csharp.com/
public class ResponseContainer
{
public List<object> Result { get; set; }
public bool IsLastPage { get; set; }
public int NextSkip { get; set; }
public int NextTake { get; set; }
public int PageCount { get; set; }
public int TotalCount { get; set; }
public string QueryResultHash { get; set; }
}
Then you can do
JsonSerializer serializer = new JsonSerializer();
ResponseContainer response = serializer.Deserialize<ResponseContainer>(jsonString);
Now you can access the fields in the json response as a C# object.

Store a JSON string in C# and then access individual parts of it

I am pulling some JSON from an API. It comes in this format:
{"yourname": {
"id": 42728521,
"name": "Your Name",
"profileIconId": 27,
"revisionDate": 1397930999000,
"summonerLevel": 1
}}
However, that is stored as:
"{\"yourname\":{\"id\":42728521,\"name\":\"Your Name\",\"profileIconId\":27,\"summonerLevel\":1,\"revisionDate\":1397930999000}}"
Inside the string.
I want to be able to call summonerLevel and for it to return the correct value.
I've been trying this:
using (var client = new WebClient())
{
api_return = client.DownloadString(api_call_key);
}
var foo = JsonConvert.DeserializeObject<Summoner>(api_return);
Console.WriteLine(Summoner.id);
Console.WriteLine(Summoner.name);
Console.WriteLine(Summoner.summonerLevel);
string id_ = foo.ToString();
Console.WriteLine(id_);
Console.ReadKey();
}
public class Summoner
{
public static int id { get; set; }
public static string name { get; set; }
public static int summonerLevel { get; set; }
}
However, that just prints out:
0
nothing
0
You have two issues here, which are both preventing you from getting the data from the JSON.
The first issue is that the properties of your Summoner class should not be static, as Vikas pointed out. Define your class like this:
public class Summoner
{
public int id { get; set; }
public string name { get; set; }
public int summonerLevel { get; set; }
}
The second issue is that your JSON structure doesn't match what you're deserializing into. The id, name and summonerLevel properties are not at the root level of the JSON, they are one level further down, inside another object. So, you'll need to deserialize into some class that "wraps" your Summoner. If the yourname property in the JSON were a fixed value, you could define a Wrapper class like this to deserialize into:
public class Wrapper
{
[JsonProperty("yourname")]
public Summoner Summoner { get; set; }
}
However, since the yourname property in the JSON is likely not a fixed value (it could change for different summoners), I would recommend deserializing into a Dictionary<string, Summoner> like this instead:
var dict = JsonConvert.DeserializeObject<Dictionary<string, Summoner>>(json);
From there, you can either loop through the dictionary key-value pairs, or, if you're only expecting one, you can use First() to get it.
var summoner = dict.First().Value;
Here is a full demo:
string json = #"{""yourname"": {
""id"": 42728521,
""name"": ""Your Name"",
""profileIconId"": 27,
""revisionDate"": 1397930999000,
""summonerLevel"": 1
}}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, Summoner>>(json);
var summoner = dict.First().Value;
Console.WriteLine(summoner.id);
Console.WriteLine(summoner.name);
Console.WriteLine(summoner.summonerLevel);
Output:
42728521
Your Name
1
Properties in Summoner class should not be static
using (var client = new WebClient())
{
api_return = client.DownloadString(api_call_key);
}
var foo = JsonConvert.DeserializeObject<Summoner>(api_return);
Console.WriteLine(foo.id);
Console.WriteLine(foo.name);
Console.WriteLine(foo.summonerLevel);
..............
}
public class Summoner
{
public int id { get; set; }
public string name { get; set; }
public int summonerLevel { get; set; }
}

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);
//...
}

Difficulty with json string deserialization

I make a web request in Silverlight for windows phone. And this is the responce.
{"result": {
"account": null,
"checkInfo": null,
"command": null,
"shifts": [
{
"description": "17:45 - 17:55 work shift",
"id": 5459,
"venueId": 132
}]}}
I use Newtonsoft.Json.dll and my purpose is to catch the array - shifts.
JObject obj = JObject.Parse(StringShifts);
JArray sh = (JArray)obj["shifts"];
But every time sh value is null. What i'm i doing wrong? Thank you in advance.
The other way around is: (This is very helpful, if you are doing more operations like this in your project)
Create these classes in your project
public class Shift
{
public string description { get; set; }
public int id { get; set; }
public int venueId { get; set; }
}
public class Result
{
public object account { get; set; }
public object checkInfo { get; set; }
public object command { get; set; }
public List<Shift> shifts { get; set; }
}
public class RootObject
{
public Result result { get; set; }
}
And then in your code
var rootObject = JsonConvert.DeserializeObject<RootObject>(StringShifts);
foreach(var shift in rootObject.result.shifts)
{
Console.Write(shift.description);
}
This way you can have more control on your json response data. But L.B 's answer if it is one time process in your app.
var obj = (JObject)JsonConvert.DeserializeObject(json);
foreach (var shift in obj["result"]["shifts"])
{
Console.WriteLine((string)shift["description"]);
}
You are missing the root results node; this is how you should use it:
JArray sh = (JArray)obj["result"]["shifts"];
Also, do note that there is a missing } in the end of your JSON sample above!

Parsing Json facebook c#

I am trying for many hours to parse a JsonArray, I have got by graph.facebook, so that i can extra values. The values I want to extract are message and ID.
Getting the JasonArry is no Problem and works fine:
[
{
"code":200,
"headers":[{"name":"Access-Control-Allow-Origin","value":"*"}],
"body":"{
\"id\":\"255572697884115_1\",
\"from\":{
\"name\":\"xyzk\",
\"id\":\"59788447049\"},
\"message\":\"This is the first message\",
\"created_time\":\"2011-11-04T21:32:50+0000\"}"},
{
"code":200,
"headers":[{"name":"Access-Control-Allow-Origin","value":"*"}],
"body":"{
\"id\":\"255572697884115_2\",
\"from\":{
\"name\":\"xyzk\",
\"id\":\"59788447049\"},
\"message\":\"This is the second message\",
\"created_time\":\"2012-01-03T21:05:59+0000\"}"}
]
Now I have tried several methods to get access to message, but every method ends in catch... and throws an exception.
For example:
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
foreach (var item in result)
{
Console.WriteLine(item.body.message);
}
throws the exception: System.Collections.Generic.Dictionary doesnt contain definitions for body. Nevertheless you see in the screenshot below, that body contains definitions.
Becaus I am not allowed to post pictures you can find it on directupload: http://s7.directupload.net/images/120907/zh5xyy2k.png
I don't havent more ideas so i please you to help me. I need this for a project, private, not commercial.
Maybe you could give me an phrase of code, so i can continue my development.
Thank you so far
Dominic
If you use Json.Net, All you have to do is
replacing
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
with
dynamic result = JsonConvert.DeserializeObject(json);
that's all.
You are not deserializing to a strongly typed object so it's normal that the applications throws an exception. In other words, the deserializer won't create an Anynymous class for you.
Your string is actually deserialized to 2 objects, each containing Dictionary<string,object> elements. So what you need to do is this:
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(s);
foreach(var item in result)
{
Console.WriteLine(item["body"]["message"]);
}
Here's a complete sample code:
void Main()
{
string json = #"[
{
""code"":200,
""headers"":[{""name"":""Access-Control-Allow-Origin"",""value"":""*""}],
""body"":{
""id"":""255572697884115_1"",
""from"":{
""name"":""xyzk"",
""id"":""59788447049""},
""message"":""This is the first message"",
""created_time"":""2011-11-04T21:32:50+0000""}},
{
""code"":200,
""headers"":[{""name"":""Access-Control-Allow-Origin"",""value"":""*""}],
""body"":{
""id"":""255572697884115_2"",
""from"":{
""name"":""xyzk"",
""id"":""59788447049""},
""message"":""This is the second message"",
""created_time"":""2012-01-03T21:05:59+0000""}}
]";
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
foreach(var item in result)
{
Console.WriteLine(item["body"]["message"]);
}
}
Prints:
This is the first message
This is the second message
I am using this simple technique
var responseTextFacebook =
#"{
"id":"100000891948867",
"name":"Nishant Sharma",
"first_name":"Nishant",
"last_name":"Sharma",
"link":"https:\/\/www.facebook.com\/profile.php?id=100000891948867",
"gender":"male",
"email":"nihantanu2010\u0040gmail.com",
"timezone":5.5,
"locale":"en_US",
"verified":true,
"updated_time":"2013-06-10T07:56:39+0000"
}"
I have declared a class
public class RootObject
{
public string id { get; set; }
public string name { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string link { get; set; }
public string gender { get; set; }
public string email { get; set; }
public double timezone { get; set; }
public string locale { get; set; }
public bool verified { get; set; }
public string updated_time { get; set; }
}
Now I am deserializing
JavaScriptSerializer objJavaScriptSerializer = new JavaScriptSerializer();
RootObject parsedData = objJavaScriptSerializer.Deserialize<RootObject>(responseTextFacebook );

Categories

Resources