I have the following JSON stored in a cookie that I wish to parse:
{"package":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"}], "hotel":[{"id":"3421","nodeId":"1234"},{"id":"8748","nodeId":"2435"}], "activity":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"},{"id":"2131","nodeId":"2342"}]}
I understand from the accepted answer on this question Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?) that you can use the following code to access individual objects within JSON notation:
JToken token = JObject.Parse(stringFullOfJson);
int page = (int)token.SelectToken("page");
int totalPages = (int)token.SelectToken("total_pages");
I've therefore adapted this into my code as follows:
HttpCookie cookie = Request.Cookies.Get("wishlist");
string JSONstring = string.Empty;
string nodeId = string.Empty;
if (cookie != null)
{
JSONstring = cookie.Value;
JToken token = JObject.Parse(JSONstring);
}
I now wish to only retreive the package array for example and loop through each of the items in this array and output the ids in the following format:
5054,8888
From the example code I sort of came up with the following approach but i'm not sure if i'm proceeding in the right direction.
JObject obj = JObject.Parse(JSONstring);
JArray packages = (JArray)obj["package"];
What is the best way of specifying one of the arrays eg. hotel, package , looping through their contents and outputting each of the id nodes that are found? The nodeId will always be numeric but the id could be a string or an int so this adds another layer of complication.
Any help would be greatly appreciated and I apologise if this is a sumwhat stupid or easy question however I have jsut started working with .Net and OO so some of the concepts are still a bit foggy.
Here's How I would Do This, I'd Create the classes required to Deserialize the JSON :-
public class JSONCookie
{
public Package[] package { get; set; }
public Hotel[] hotel { get; set; }
public Activity[] activity { get; set; }
}
public class Package
{
public string id { get; set; }
public string nodeId { get; set; }
}
public class Hotel
{
public string id { get; set; }
public string nodeId { get; set; }
}
public class Activity
{
public string id { get; set; }
public string nodeId { get; set; }
}
Now, I would Create a method that actually does the deserialising :-
public JSONCookie GetJSONCookieResponse()
{
try
{
// Add your own code that gets the Response Here.
// string response = "{"package":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"}], "hotel":[{"id":"3421","nodeId":"1234"},{"id":"8748","nodeId":"2435"}], "activity":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"},{"id":"2131","nodeId":"2342"}]}";
//return new JsonSerializer().Deserialize<JSONCookie>(new JsonTextReader(new StringReader(response)));
}
catch
{
return null;
}
}
From the JSONCookie Object that is returned, you can then use LINQ to pick out what you need like follows :-
x.package.Select(p=>p.id);
After a lot of trawling Google, this is the easiest solution I have come up with:
HttpCookie cookie = Request.Cookies.Get("wishlist");
string JSONstring = string.Empty;
string nodeId = string.Empty;
string test = string.Empty;
if (cookie != null)
{
JSONstring = cookie.Value;
JObject obj = JObject.Parse(JSONstring);
JArray packages = (JArray)obj["package"];
foreach (var item in packages.Children()){
var properties = item.Children<JProperty>();
var idElement = properties.FirstOrDefault(x => x.Name == "id");
var myElementValue = idElement.Value;
test = test + myElementValue + ",";
}
}
This will output all ids in the packages array in a CSV format (with a trailing ,)
Related
So I've looked around for tutorials on this and all the tutorials I've found doesn't have JSON that looks like the one I'm trying to parse.
I'm trying to parse JSON from this website https://www.steamcardexchange.net/api/request.php?GetBadgePrices_Guest
Since it doesn't have any identifiers for each thing like name, id etc I'm not sure how I will go about extracting data from it.
My only interest is really getting the first number of each item
[["449940","! That Bastard Is Trying To Steal Our Gold !"],5,"$0.64","1519294200"]
so what I want to extract from this item would be "449940".
This is what I've got so far
using (var client = new WebClient())
{
client.DownloadFile("https://www.steamcardexchange.net/api/request.php?GetBadgePrices_Guest", "data.json");
}
using (StreamReader r = new StreamReader("data.json"))
{
string json = r.ReadToEnd();
//Parse somehow
}
Any tips?
I took this up out of sheer curiosity because I had no idea how to parse this either. Perhaps there's a much better way.
I started by pasting a fragment of this into json2csharp.com.
The class it generates is
public class RootObject
{
public List<List<object>> data { get; set; }
}
From there I wrote some classes that correspond to what I think the data is supposed to look like. The names of the classes and properties are meaningless, so change them to whatever these actually represent.
public class OutputItem
{
public Message Message { get; set; }
public long Int64Value { get; set; } // 5
public string StringThatLooksLikeCurrency { get; set; } // "$0.64"
public string StringThatLooksNumeric { get; set; } // "1519294200"
}
public class Message
{
public string MessageId { get; set; } // "449940"
public string MessageText { get; set; } // "! That Dude..."
}
And finally, some sample code that takes a fragment of that JSON and converts it to a list of OutputItem. In order to figure this out I first deserialized the JSON to RootObject, then I inspected the deserialized object in the debugger to make sense of what it looked like.
var json = #"{ ""data"": [[[ ""449940"", ""! That Dude Is Trying To Steal Our Gold !"" ], 5, ""$0.64"", ""1519294200"" ], [[ ""303720"", ""#killallzombies"" ], 5, ""$0.56"", ""1519322799"" ]]}";
var parsed = JsonConvert.DeserializeObject<RootObject>(json);
var outputItems = new List<OutputItem>();
foreach (var listOfObject in parsed.data)
{
var outputItem = new OutputItem();
var message = (JArray) listOfObject[0];
outputItem.Message = new Message {MessageId = (string) message[0],
MessageText = (string) message[1]};
outputItem.Int64Value = (long) listOfObject[1];
outputItem.StringThatLooksLikeCurrency = (string) listOfObject[2];
outputItem.StringThatLooksNumeric = (string) listOfObject[3];
outputItems.Add(outputItem);
}
I am calling a REST service from my C# application which connects to CRM.
This returns HttpResponseMessage.
response.Content.ReadAsStringAsync().Result
The above statement returns following output. I need to convert this to Account object, which already has "accountnumber, and accountid properties.
{
"#odata.context":"https://APIURL/api/data/v8.1/$metadata#account(accountnumber)","value":[
{
"#odata.etag":"W/\"12496866\"","accountnumber":"D00208","accountid":"30417c0f-7b8c-e611-80f3-5065f38bd4d1"
} ] }
I have tried following code
Account return = JsonConvert.DeserializeObject<Account>(response.Content.ReadAsStringAsync().Result);
But this doesn't fill up the object, and it always has null values in accountnumber, and accountid fields.
Any idea of how to properly convert this response to the C# type.
you should do it like this -
public class Value
{
[JsonProperty("#odata.etag")]
public string etag { get; set; }
public string accountnumber { get; set; }
public string accountid { get; set; }
}
public class RootObject
{
[JsonProperty("#odata.context")]
public string context { get; set; }
public List<Value> value { get; set; }
}
then deserialize-
var value = JsonConvert.DeserializeObject<RootObject>(json);
We can parse and create Anonymous Type based on that. In your case, replace the Anonymous Type with Account object.
Given the JSON string:
string json = #"{
'#odata.context':'https://APIURL/api/data/v8.1/$metadata#account(accountnumber)',
'value':[
{
'#odata.etag':'W/\'12496866\'',
'accountnumber':'D00208',
'accountid':'30417c0f-7b8c-e611-80f3-5065f38bd4d1'
}
]
}";
It can be parsed as below:
var jsonObject = JObject.Parse(json);
var dataObject = new
{
Context = jsonObject["#odata.context"],
Values = jsonObject["value"].AsEnumerable<JToken>()
.Select(v => new
{
ETag = v["#odata.etag"],
AccountNumber = v["accountnumber"],
AccountId = v["accountid"]
}).ToArray()
};
In order to convert to Account object where the object is defined as below:
public class Account
{
public string Number { get; set; }
public string Id { get; set; }
}
Then the JSON object can be parsed as below (if looking for only first node; It can also be converted to list of Accounts:
var jsonObject = JObject.Parse(json);
var account = jsonObject["value"].AsEnumerable<JToken>()
.Select(v => new Account()
{
Number = v["accountnumber"].ToString(),
Id = v["accountid"].ToString()
}).FirstOrDefault();
You can generalize the accepted answer by using a generic class to deserialize json web response:
class RootObject<T>
{
public List<T> Value { get; set; }
}
var odata = JsonConvert.DeserializeObject<RootObject<POCO>>(json);
Try it with live Demo
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 developing an app for iOS using Xamarin Studio (C#) in Mac OS X. I want to get a list of the user's friends on Facebook, so I added Facebook's component from Xamarin's component store and made a request(code at the bottom). This is the response I get:
{
data = (
{
"first_name" = Dev;
id = 100001438778777;
"last_name" = Accu;
}
);
paging = {
next = "https://graph.facebook.com/v2.0/100005203000814/friends?fields=id,first_name,last_name&format=json&access_token=CAAK3hGOIm2ABANPUcr2QU1t8gqLNsZCJBrc8ZCZCqUSwHkX2f43VHarvc1ZABbjDrY7jIO0OT5ZBRBiZC1audQnIvxCsOu60y30iR84jVa56beNTptixj7AFqT92ZBGdyxDshFHHxkFDgCg9JyRZBYfqaGKkeJkuxJVUXDq8eR8ZCmRlslpOVSavQZC1hCcxOwdgFS2jWQdGZBFVSYTkrhkavfP&limit=5000&offset=5000&__after_id=enc_Aey-LjP59ZnmKMcZKcEr94tTUPIHIvWj9JnMwkIVSvxJ9RBYBqhBt3bGKlURY4SHBCDeH8BM_wSsqICzEFgKiZvh";
};
}
There is 2 problems with this response, it only includes 1 friend for some unknown reason, and the JSON is not valid, so ultimately parsing this fails. The following is the code I use to make the request:
var friendsRequest = await new FBRequest(FBSession.ActiveSession, "/me/friends?fields=id,first_name,last_name").StartAsync();
var friendsArray = friendsRequest.Result as MonoTouch.Foundation.NSMutableDictionary;
var response = FriendResponse.FromJson(friendsArray.ToString());
List<FacebookProfile> friends = new List<FacebookProfile>();
foreach (var friend in response.Data)
{
friends.Add(new FacebookProfile(friend.ID, friend.FirstName, friend.LastName));
}
And here is the parsing classes:
public class NextPage
{
public string Next { get; set; }
}
public class Friend
{
public string ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class FriendResponse
{
public List<Friend> Data { get; set; }
public NextPage Paging { get; set; }
public static FriendResponse FromJson(string json)
{
JsConfig.EmitLowercaseUnderscoreNames = true;
return JsonSerializer.DeserializeFromString<FriendResponse>(json);
}
}
The component is a 1:1 binding to the objective-c SDK. The response that Facebook returns is an NSDictionary underneath, and if you run ToString() on it, it will return the string representation of the NSDictionary which is totally different from a JSON
string. What you have to do is serialize that NSDictionary object back into a JSON string. Here is an example of how to do this:
var friendsRequest = await new FBRequest(FBSession.ActiveSession, "/me/friends?fields=id,first_name,last_name").StartAsync();
// Convert back the object into a Json
NSError error;
var jsonData = NSJsonSerialization.Serialize (friendsRequest.Result, 0, out error);
var jsonString = (string) NSString.FromData (jsonData, NSStringEncoding.UTF8);
var response = FriendResponse.FromJson(jsonString);
"jsonString" will have the correct JSON string data representation this time.
Courtesy of Alex DeSoto. =)
I have an array of objects like this in json format:
{"results":[{"SwiftCode":"","City":"","BankName":"Deutsche Bank","Bankkey":"10020030","Bankcountry":"DE"},{"SwiftCode":"","City":"10891 Berlin","BankName":"Commerzbank Berlin (West)","Bankkey":"10040000","Bankcountry":"DE"}]}
What I want to get is a object[] in C#, where one object contains all the data what is in one json object. The thing is, I can NOT make a class with the properties of this object like here:
public class Result
{
public int SwiftCode { get; set; }
public string City { get; set; }
// .
// .
public string Bankcountry { get; set; }
}
Because I get everytime different results back, but I know it's always an array of objects. Someone knows how I could manage to get an array of objects back?
EDIT
I have to pass this object to powershell via WriteObject(results). So the ouput should only be the object IN the array.
Though this is an old question, I thought I'd post my answer anyway, if that helps someone in future
JArray array = JArray.Parse(jsonString);
foreach (JObject obj in array.Children<JObject>())
{
foreach (JProperty singleProp in obj.Properties())
{
string name = singleProp.Name;
string value = singleProp.Value.ToString();
//Do something with name and value
//System.Windows.MessageBox.Show("name is "+name+" and value is "+value);
}
}
This solution uses Newtonsoft library, don't forget to include using Newtonsoft.Json.Linq;
Use newtonsoft like so:
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
class Program
{
static void Main()
{
string json = "{'results':[{'SwiftCode':'','City':'','BankName':'Deutsche Bank','Bankkey':'10020030','Bankcountry':'DE'},{'SwiftCode':'','City':'10891 Berlin','BankName':'Commerzbank Berlin (West)','Bankkey':'10040000','Bankcountry':'DE'}]}";
var resultObjects = AllChildren(JObject.Parse(json))
.First(c => c.Type == JTokenType.Array && c.Path.Contains("results"))
.Children<JObject>();
foreach (JObject result in resultObjects) {
foreach (JProperty property in result.Properties()) {
// do something with the property belonging to result
}
}
}
// recursively yield all children of json
private static IEnumerable<JToken> AllChildren(JToken json)
{
foreach (var c in json.Children()) {
yield return c;
foreach (var cc in AllChildren(c)) {
yield return cc;
}
}
}
}
Use NewtonSoft JSON.Net library.
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
Hope this helps.
I have just got an solution a little bit easier do get an list out of an JSON object. Hope this can help.
I got an JSON like this:
{"Accounts":"[{\"bank\":\"Itau\",\"account\":\"456\",\"agency\":\"0444\",\"digit\":\"5\"}]"}
And made some types like this
public class FinancialData
{
public string Accounts { get; set; } // this will store the JSON string
public List<Accounts> AccountsList { get; set; } // this will be the actually list.
}
public class Accounts
{
public string bank { get; set; }
public string account { get; set; }
public string agency { get; set; }
public string digit { get; set; }
}
and the "magic" part
Models.FinancialData financialData = (Models.FinancialData)JsonConvert.DeserializeObject(myJSON,typeof(Models.FinancialData));
var accounts = JsonConvert.DeserializeObject(financialData.Accounts) as JArray;
foreach (var account in accounts)
{
if (financialData.AccountsList == null)
{
financialData.AccountsList = new List<Models.Accounts>();
}
financialData.AccountsList.Add(JsonConvert.DeserializeObject<Models.Accounts>(account.ToString()));
}
Using .NET 6 you could use built in System.Text.Json.Nodes
Example:
string json = #"{""results"":[{""SwiftCode"":"""",""City"":"""",""BankName"":""Deutsche Bank"",""Bankkey"":""10020030"",""Bankcountry"":""DE""},{""SwiftCode"":"""",""City"":""10891 Berlin"",""BankName"":""Commerzbank Berlin (West)"",""Bankkey"":""10040000"",""Bankcountry"":""DE""}]}";
JsonObject obj = JsonNode.Parse(json).AsObject();
JsonArray jsonArray = (JsonArray)obj["results"];
I believe this is much simpler;
dynamic obj = JObject.Parse(jsonString);
string results = obj.results;
foreach(string result in result.Split('))
{
//Todo
}