I need to parse a JSON, I am already parsing the first part of the record but I am having a problem with a sub record. This is my code:
List<JToken> results = new List<JToken>();
List<JToken> results2 = new List<JToken>();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
results = JObject.Parse(result).SelectToken("record").ToList();
}
List<Record> users = new List<Record>();
foreach (JObject token in results)
{
Record user = new Record();
user.id = Int32.Parse(token["id"].ToString());
user.full_name = token["full_name"].ToString();
user.email = token["email"].ToString();
//role.RoleName = token.SelectToken("name").ToString();
}
That's working perfectly but I have issues parsin a string that's a bit deeper. This is the JSON:
{
"record": [
{
"id": 2,
"institution_id": 1,
"full_name": "",
"email": "",
"role_id": 2,
"created": "2015-01-13 01:18:52.370379",
"updated": "2015-01-22 23:58:44.103636",
"branch_id": 1,
"Branch_by_branch_id": {
"id": 1,
"institution_id": 1,
"branch_name": "Test Branch"
}
}
]
}
I want to get the "branch_name" inside Branch_by_branch_id. How can I access it with Jobject?
If your JSON is this
{
"record": [
{
"id": 26,
"full_name": "",
"email": "",
"branch_id": 1,
"Branch_by_branch_id": {
"id": 1,
"institution_id": 1,
"branch_name": "NAME"
}
}
]
}
Have classes like this:
public class BranchByBranchId
{
public int id { get; set; }
public int institution_id { get; set; }
public string branch_name { get; set; }
}
public class Record
{
public int id { get; set; }
public string full_name { get; set; }
public string email { get; set; }
public int branch_id { get; set; }
public BranchByBranchId Branch_by_branch_id { get; set; }
}
public class RootObject
{
public List<Record> record { get; set; }
}
Then parse it and retrieve the value like this.
var root = JsonConvert.DeserializeObject<RootObject>(json);
var branchName = root[0].Branch_by_branch_id.branch_name;
I always prefer to access my JSON objects like this, because I like having my objects as native C# classes. The classes were generated by json2csharp.
Related
I have a situation while working with a JSON response from an API. To give a background, I am consuming an API from a source using a REST API using 3.5 .net framework.
Below is the part of the JSON output and I am kind of struggling to use it.
a)
"value": {
"Description": "Total Calculated things",
"2018": "5,820,456 ",
"2019": "2,957,447 "
}
The last 2 elements are dynamic, those are tend to change in API response. I was expecting the format like I have mentioned below, but at this point of given time the source provider is not able to change it as the API is used in many other different programs. And Changing the things in the source API will make other program owners to change.
b)
"value": {
"Description": "Total Calculated EQUITY AND LIABILITIES",
"YearData": [ {
"Data": "5,820,456",
"Year": "2018"
},
{
"Data": "2,957,447 ",
"Year": "2019"
} ]
}
Is there any way to overcome such thing> Any way to convert a to b?
EDIT
#Xerillio , Thanks . How can I achieve the same using below JSON format.
var json = #"
{
""entityData"": [
{
""name"": ""Statement of Comprehensive Income"",
""subattrOutput"": [
{
""name"": ""Sales"",
""subattrOutput"": [],
""value"": {
""Description"": ""Sales "",
""2018"": ""8,704,888 "",
""2019"": ""4,760,717 ""
},
""score"": ""99.5"",
""valuetype"": ""object""
},
{
""name"": ""Cost of goods sold"",
""subattrOutput"": [],
""value"": {
""Description"": ""Cost of sales "",
""2018"": ""(6,791,489) "",
""2019"": ""(3,502,785) ""
},
""score"": ""99.75"",
""valuetype"": ""object""
}
],
""value"": null,
""score"": ""98.63"",
""valuetype"": ""object""
}
]
}";
I wish this was more easy, but i just got it here:
class Program
{
static async Task Main(string[] args)
{
string json1 = #"{""value"": {""Description"": ""Total Calculated things"",""2018"": ""5,820,456 "",""2019"": ""2,957,447 ""}}";
string json2 = #"{""value"": {""Description"": ""Total Calculated EQUITY AND LIABILITIES"",""YearData"": [ {""Data"": ""5,820,456"",""Year"": ""2018""},{""Data"": ""2,957,447 "",""Year"": ""2019""} ]}}";
var obj1 = JsonConvert.DeserializeObject<ObjectResult>(json1);
var obj2 = JsonConvert.DeserializeObject<ObjectResult>(json2);
var res1 = CastObject<Result1>(obj1.Value.ToString());
var res2 = CastObject<Result2>(obj2.Value.ToString());
var invalidRes1 = CastObject<Result1>(obj2.Value.ToString());
var invalidRes2 = CastObject<Result2>(obj1.Value.ToString());
Console.WriteLine(res1);
Console.WriteLine(res2);
}
public static T CastObject<T>(string obj)
{
return !TryCastObject(obj, out T result) ? default : result;
}
public static bool TryCastObject<TOut>(string objToCast, out TOut obj)
{
try
{
obj = JsonConvert.DeserializeObject<TOut>(objToCast);
return true;
}
catch
{
obj = default;
return false;
}
}
}
public class ObjectResult
{
public object Value { get; set; }
}
public class Result1
{
[JsonProperty(PropertyName = "description")] public string Description { get; set; }
[JsonProperty(PropertyName = "2018")] public string _2018 { get; set; }
[JsonProperty(PropertyName = "2019")] public string _2019 { get; set; }
}
public class Result2
{
[JsonProperty(PropertyName = "Description")] public string Description { get; set; }
[JsonProperty(PropertyName = "YearData")] public List<YearData> YearData { get; set; }
}
public class YearData
{
[JsonProperty(PropertyName = "Data")] public string Data { get; set; }
[JsonProperty(PropertyName = "Year")] public string Year { get; set; }
}
It is A LOT of work and sincerely, as there more nodes in the json i think that using JObject is the best option, and you will have to do a deserealization in more than 1 step :(
Depending on how large the JSON structure is you could deserialize it into a Dictionary and manually map it to the proper format:
var json = #"
{
""value"": {
""Description"": ""Total Calculated things"",
""2018"": ""5,820,456 "",
""2019"": ""2,957,447 ""
}
}";
var badObj = JsonSerializer.Deserialize<BadFormat>(json);
var result = new WrapperType
{
Value = new ProperlyFormattedType()
};
foreach (var pair in badObj.Value)
{
if (pair.Key == "Description")
{
result.Value.Description = pair.Value;
}
else if (int.TryParse(pair.Key, out int _))
{
result.Value.YearData
.Add(new DatedValues
{
Year = pair.Key,
Data = pair.Value
});
}
}
// Data models...
public class BadFormat
{
[JsonPropertyName("value")]
public Dictionary<string, string> Value { get; set; }
}
public class WrapperType
{
public ProperlyFormattedType Value { get; set; }
}
public class ProperlyFormattedType
{
public string Description { get; set; }
public List<DatedValues> YearData { get; set; } = new List<DatedValues>();
}
public class DatedValues
{
public string Year { get; set; }
public string Data { get; set; }
}
See an example fiddle here.
I have the following json response
{
"Id": "1234",
"Name": "Test",
"Orders": [
{
"OrderId": "87654",
"OrderDetails": {
"OrdId": "1234",
"Name": "Desk"
}
},
{
"OrderId": "54213",
"OrderDetails": {
"OrdId": "4321",
"Name": "Table"
}
}
]
}
I want to search the list of orders to see if there is an OrderId of 87654.
I can do with an array , but how can I do it with Linq ?
You can deserialize the json string to a JObject using Newtonsoft.Json and then loop through the orders to get the OrderIDs.
var obj = JObject.Parse(json);
foreach(var order in obj["Orders"])
{
Console.WriteLine(order["OrderId"]);
}
or you can use the Where clause.
var myOrder = obj["Orders"].Where(x => x["OrderId"].ToString().Equals("87654")).FirstOrDefault();
Then you can print any property of that order,
Console.WriteLine(myOrder["OrderDetails"]["Name"].ToString());
// Prints: Desk
Alternatively, you can: also use classes to deserialize the json you have and query the orders.
public class OrderDetails
{
public string OrdId { get; set; }
public string Name { get; set; }
}
public class Order
{
public string OrderId { get; set; }
public OrderDetails OrderDetails { get; set; }
}
public class RootObject
{
public string Id { get; set; }
public string Name { get; set; }
public List<Order> Orders { get; set; }
}
public static void Main(string[] args)
{
string json = File.ReadAllText(#"C:\temp\json.txt");
var obj = JsonConvert.DeserializeObject<RootObject>(json);
var myOrder = obj.Orders.FirstOrDefault(x => x.OrderId.Equals("87654"));
if (myOrder != null)
{
Console.WriteLine(myOrder.OrderDetails.Name);
}
}
Demo on dotnet fiddle
You can use Newtonsoft to achieve it
var jsonData = "{ 'Id': '1234', 'Name': 'Test', 'Orders': [ {'OrderId': '87654', 'OrderDetails': { 'OrdId': '1234', 'Name': 'Desk' } }, { 'OrderId': '54213', 'OrderDetails': { 'OrdId': '4321','Name': 'Table' }}]}";
var desirializedData = JsonConvert.DeserializeObject<MyObject>(jsonData);
var result = desirializedData.Orders.Where(p => p.OrderId == 87654);
foreach(var master in result)
{
Console.WriteLine(master.OrderId + " " + master.OrderDetails.Name);
}
Consider the following json:
{
"0": {
"id": "1",
"email": "someemail#test.com",
"tstamp": "2019-01-21 11:19:48",
"times": "2",
"tstamp_iso": "2019-01-21T12:19:48-05:00"
},
"1": {
"id": "2",
"email": "someotheremail#test.com",
"tstamp": "2019-01-21 11:25:48",
"times": "2",
"tstamp_iso": "2019-01-21T12:25:48-05:00"
},
"result_code": 1,
"result_message": "Success!",
"result_output": "json"
}
I am trying to convert that data into a c# object, however, I'm not sure how to go about the array value as it has 0, 1 for its name instead of it being nested in an array and it will go on up until 20 if there are 20 results. I can't change the json data.
I got this far:
[JsonObject]
public class FirstObject
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "email")]
public string Email { get; set; }
[JsonProperty(PropertyName = "tstamp")]
public string TimeStamp { get; set; }
[JsonProperty(PropertyName = "times")]
public string Times { get; set; }
[JsonProperty(PropertyName = "tstamp_iso")]
public string TimeStampIso { get; set; }
}
[JsonObject]
public class SecondObject
{
public FirstObject[] FirstObjects { get; set; }
[JsonProperty(PropertyName = "result_code")]
public string ResultCode { get; set; }
[JsonProperty(PropertyName = "result_message")]
public string ResultMessage { get; set; }
[JsonProperty(PropertyName = "result_output")]
public string ResultOutput { get; set; }
}
What I don't understand is how to map FirstObjects to results of 0, 1, ... 20. I am hoping there is a better way than writing out that 20 times and setting the name to 0, or 1, etc...
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace ConsoleApp2
{
class Program
{
const string json = #"{
""0"": {
""id"": ""1"",
""email"": ""someemail#test.com"",
""tstamp"": ""2019-01-21 11:19:48"",
""times"": ""2"",
""tstamp_iso"": ""2019-01-21T12:19:48-05:00""
},
""1"": {
""id"": ""2"",
""email"": ""someotheremail#test.com"",
""tstamp"": ""2019-01-21 11:25:48"",
""times"": ""2"",
""tstamp_iso"": ""2019-01-21T12:25:48-05:00""
},
""result_code"": 1,
""result_message"": ""Success!"",
""result_output"": ""json""
}";
static void Main(string[] args)
{
JObject o = JObject.Parse(json);
List<FirstObject> l = new List<FirstObject>();
int c = 0;
while (o[$"{c}"] != null)
{
FirstObject fo = o[$"{c++}"].ToObject<FirstObject>();
l.Add(fo);
}
SecondObject so = JsonConvert.DeserializeObject<SecondObject>(json);
so.FirstObjects = l.ToArray();
Console.ReadKey();
}
}
}
I want to get "id" "gender", "name", "picture" from a this json response string
{
"data": [{
"name": "XXX",
"gender": "male",
"id": "528814",
"picture": {
"data": {
"is_silhouette": false,
"url": "https:\/\/fbcdn-profile-a.akamaihd.net\/hprofile-ak-frc3\/v\/t1.0-1\/p50x50\/551182_10152227358459008__n.jpg?oh=983b70686285c2f60f71e665ace8ed5f&oe=54C1220C&__gda__=1422017140_998fbe013c4fe191ccadfdbc77693a76"
}
}
}
string[] data = friendsData.Split(new string[] { "}," }, StringSplitOptions.RemoveEmptyEntries).ToArray();
foreach (string d in data)
{
try
{
FacebookFriend f = new FacebookFriend
{
id = d.Substring("\"id\":\"", "\""),
gender = d.Substring("gender\":\"", "\""),
name = d.Substring("name\":\"", "\""),
picture = d.Substring("\"picture\":{\"data\":{\"url\":\"", "\"").Replace(#"\", string.Empty)
};
FacebookFriendList.Add(f);
}
catch
{
continue;
}
}
This code looks bad if the json data changes then you need to modify your logic accordingly. I would suggest you to serialize and deserialize the model data using Json serialization.
Model:
public class SerializationModel
{
public Data Data { get; set; }
}
public class Data
{
public string Name { get; set; }
public string Gender { get; set; }
public string Id { get; set; }
public Picture Picture { get; set; }
}
public class Picture
{
public PictureData Data { get; set; }
}
public class PictureData
{
public bool is_silhouette { get; set; }
public string url { get; set; }
}
Serialize your data to get the json output is like,
SerializationModel serializationModel = new SerializationModel
{
Data = new Data
{
Gender = "mALE",
Id = "88",
Name = "User",
Picture = new Picture
{
Data = new PictureData
{
is_silhouette = true,
url = "www.google.com"
}
}
}
};
string serializedString = Newtonsoft.Json.JsonConvert.SerializeObject(serializationModel);
which would yield the below result,
{"Data":{"Name":"User","Gender":"mALE","Id":"88","Picture":{"Data":{"is_silhouette":true,"url":"www.google.com"}}}}
To deserialize the json data back to the model,
SerializationModel sm = Newtonsoft.Json.JsonConvert.DeserializeObject<SerializationModel>(serializedString);
Then you can get the required values from the model itself.
I have following json:
{
"serverTime": "2013-08-12 02:45:55,558",
"data": [
{
"key1": 1,
"key2": {},
"key3": {
"key4": [
""
],
"key5": "test2"
},
"key7": 0
},
{
"key8": 1,
"key9": {},
"key10": {
"key4": [
""
],
"key9": "test2"
},
"key11": 0
}
]
}
I want to get values as key value pair. Something like:
jsonObject[data][0]
should give first item of the data array.
I am using JSONFx.net. But it gives strongly typed objects. I do not want that.
Is there any way to parse JSON as key value as I mentioned earlier?
Thanks
Try this:
using System;
using System.IO;
using Newtonsoft.Json;
class Program
{
static void Main(string[] args)
{
var json = File.ReadAllText("input.txt");
var a = new { serverTime = "", data = new object[] { } };
var c = new JsonSerializer();
dynamic jsonObject = c.Deserialize(new StringReader(json), a.GetType());
Console.WriteLine(jsonObject.data[0]);
}
}
If you're not averse to using Json.NET, you can do this:
var jsonString = #"
{
""serverTime"": ""2013-08-12 02:45:55,558"",
""data"": [
{
""key1"": 1,
""key2"": {},
""key3"": {
""key4"": [
""""
],
""key5"": ""test2""
},
""key7"": 0
},
{
""key8"": 1,
""key9"": {},
""key10"": {
""key4"": [
""""
],
""key9"": ""test2""
},
""key11"": 0
}
]
}";
var jsonResult = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
var firstItem = jsonResult["data"][0];
firstItem would be an array of the first item in the data array:
Hope this helps.
First create classes to parse string
public class Key2
{
}
public class Key3
{
public List<string> key4 { get; set; }
public string key5 { get; set; }
}
public class Key9
{
}
public class Key10
{
public List<string> key4 { get; set; }
public string key9 { get; set; }
}
public class Datum
{
public int key1 { get; set; }
public Key2 key2 { get; set; }
public Key3 key3 { get; set; }
public int key7 { get; set; }
public int? key8 { get; set; }
public Key9 key9 { get; set; }
public Key10 key10 { get; set; }
public int? key11 { get; set; }
}
public class RootObject
{
public string serverTime { get; set; }
public List<Datum> data { get; set; }
}
add reference of Newtonsoft.Json.dll
RootObject obj = JsonConvert.DeserializeObject<RootObject>(jsonData);
then you can access values .
If you want to do this without third party libraries then do:
I would use the following code:
var deserializer = new JavaScriptSerializer();
var someObject = deserializer.DeserializeObject(json);
string serverTime = someObject["serverTime"].ToString();
Dictionary<string, int> data = someObject["data"] as Dictionary<string, int>;
Give it a go.
Edit: You may need to change the last line to:
Dictionary<string, int?> data = someObject["data"] as Dictionary<string, int?>;