Cycling through Json objects - c#

Fairly new to working with Json and having troubles
[{"page":1,"example":
[{"number":6666666,"Year":2005}]},
{"page":2,"example":
[{"number":555555,"Year":2000}]}]
This is my Json, it's just an example and not actually Json that i'm using but set out the same way
I been using the following c# to get the values within page 1 of the Json but i need help getting the values from page 2 and so forth
var http = new HttpClient();
var response = await http.GetAsync("Example.json");
var result = await response.Content.ReadAsStringAsync();
List<Rootobject> RootList = JsonConvert.DeserializeObject<List<Rootobject>>(result);
foreach (Rootobject item in RootList)
{
listBox1.Items.Add(item.Example[0].number.ToString());
}
Lastly my Classes are
public class Thread
{
[JsonProperty("number")]
public int number { get; set; }
[JsonProperty("year")]
public int year { get; set; }
}
public class Rootobject
{
[JsonProperty("page")]
public int page { get; set; }
[JsonProperty("example")]
public List<Example> example{ get; set; }
}

You can use LINQ expression
var data = var i in RootList
where i.page == 2; // here you can replace the number as per your requirement
Method to return required data
Public Rootobject GetDataByPage(int pageNo) {
return RootList.FirstOrDefault(x => x.page == pageNo);
}

Related

How can I parse some JSON dynamically without knowing JSON values?

So I am using TDAmeritrade API to receive stock data with a C# Winforms program on Visual Studio. It takes the user input stock symbol and searches for the info. I am using HttpClient and Newtonsoft.Json and have been able to successfully perform the GET request and receive a JSON string back, but I do not know how to get all of the information I need out of it.
Here is the JSON:
https://drive.google.com/file/d/1TpAUwjyqrHArEXGXMof_K1eQe0hFoaw5/view?usp=sharing
Above is the JSON string sent back to me then formatted. My goal is to record information for each price in "callExpDateMap.2021-02-19:11" and "callExpDateMap.2021-03-19:39". The problem is that for each different stock, the dates that show up in "callExpDateMap" are going to be different.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await client.GetAsync(url);
var info = await response.Content.ReadAsStringAsync();
dynamic config = JsonConvert.DeserializeObject<dynamic>(info, new ExpandoObjectConverter());
return config;
This is the code I have right now. I know the last for statement is not correct. How can I parse to the specific sections I want (callExpDateMap.expirationdate.StrikePrice) and get the information needed from each without knowing the dates and Strike prices beforehand? Is there a way to innumerate it and search through the JSON as if it were all a bunch of arrays?
The code below is perhaps not the most elegant nor complete, but I think it will get you going. I would start by using the JObject.Parse() from the Newtonsoft.Json.Linq namespace and take it from there.
JObject root = JObject.Parse(info);
string symbol = root["symbol"].ToObject<string>();
foreach (JToken toplevel in root["callExpDateMap"].Children())
{
foreach (JToken nextlevel in toplevel.Children())
{
foreach (JToken bottomlevel in nextlevel.Children())
{
foreach (JToken jToken in bottomlevel.Children())
{
JArray jArray = jToken as JArray;
foreach (var arrayElement in jArray)
{
InfoObject infoObject = arrayElement.ToObject<InfoObject>();
Console.WriteLine(infoObject.putCall);
Console.WriteLine(infoObject.exchangeName);
Console.WriteLine(infoObject.multiplier);
}
}
}
}
}
public class InfoObject
{
public string putCall { get; set; }
public string symbol { get; set; }
public string description { get; set; }
public string exchangeName { get; set; }
// ...
public int multiplier { get; set; }
// ...
}
This is official documentation of Newtonsoft method you are trying to use.
https://www.newtonsoft.com/json/help/html/Overload_Newtonsoft_Json_JsonConvert_DeserializeObject.htm
If an API's method returns different json propeties and you cannot trust it's property names all the times, then you can try using a deserialize method that returns .Net object, for example: JsonConvert.DeserializeObject Method (String)
https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonConvert_DeserializeObject.htm
That method's signature is this:
public static Object DeserializeObject(string value)
Parameter is: value of type json string.
Return Value is: Object of type object.
If you do not want an Object, then you can of course use a .Net type you have. Such as this method:
JsonConvert.DeserializeObject Method (String)
Any property that you have in both (the .net type and json object) will get populated. If .net type has properties that do not exist in json object, then those will be ignored. If json object has properties that do not exist in.net, then those will be ignored too.
Here's an example of a .Net type
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace MyNameSpace
{
public class TDAmeritradeStockData
{
[JsonProperty("symbol")]
public string Symbol { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("callExpDateMap")]
public object CallExpDateMap { get; set; }
//...
//...
public CallExpDateMapType[] CallExpDateMapList { get; set; }
}
public class CallExpDateMapType
{
[JsonProperty("expirationdate")]
public string Expirationdate { get; set; }
[JsonProperty("StrikePrice")]
public List<StrikePriceType> StrikePriceList { get; set; }
}
public class StrikePriceType
{
public string StrikePrice { get; set; }
public List<StrikePricePropertiesType> StrikePricePropertiesList { get; set; }
}
public class StrikePricePropertiesType
{
[JsonProperty("putCall")]
public string PutCall { get; set; }
[JsonProperty("symbol")]
public string Symbol { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("exchangeName")]
public string ExchangeName { get; set; }
[JsonProperty("bid")]
public double Bid { get; set; }
[JsonProperty("ask")]
public double Ask { get; set; }
//...
//...
}
[TestClass]
public class TestTestTest
{
[TestMethod]
public void JsonTest()
{
var jsondata = ReadFile("data.json");
var model = JsonConvert.DeserializeObject<TDAmeritradeStockData>(jsondata);
JObject jObject = (JObject)model.CallExpDateMap;
var count = ((JObject)model.CallExpDateMap).Count;
model.CallExpDateMapList = new CallExpDateMapType[count];
var jToken = (JToken)jObject.First;
for (var i = 0; i < count; i++)
{
model.CallExpDateMapList[i] = new CallExpDateMapType
{
Expirationdate = jToken.Path,
StrikePriceList = new List<StrikePriceType>()
};
var nextStrikePrice = jToken.First.First;
while (nextStrikePrice != null)
{
var nextStrikePriceProperties = nextStrikePrice;
var srikePriceList = new StrikePriceType
{
StrikePrice = nextStrikePriceProperties.Path,
StrikePricePropertiesList = JsonConvert.DeserializeObject<List<StrikePricePropertiesType>>(nextStrikePrice.First.ToString())
};
model.CallExpDateMapList[i].StrikePriceList.Add(srikePriceList);
nextStrikePrice = nextStrikePrice.Next;
}
jToken = jToken.Next;
}
Assert.IsNotNull(model);
}
private string ReadFile(string fileName)
{
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
var data = new StringBuilder();
using (var streamReader = new StreamReader(fileStream))
{
while (!streamReader.EndOfStream) data.Append(streamReader.ReadLine());
streamReader.Close();
}
fileStream.Close();
return data.ToString();
}
}
}
}

Having trouble converting multi-level JSON string into object list. Any suggestions?

Hey all so here is the JSON string I expect back {\"status\":\"success\",\"locations\":[{\"id\":\"24\",\"name\":\"Test New Location Test\",\"contact_first_name\":\"Test\",\"contact_last_name\":\"Test\",\"contact_email\":\"test#email.com\",\"contact_phone_number\":\"(555) 555-5555\",\"billing_address\":\"Test\",\"billing_city\":\"Test\",\"billing_state\":\"AK\",\"billing_zip\":\"55555\",\"traps\":[]}]}
I am trying to store all the different parts that make up a location to an object list such as id, name, contact_first_name etc.. I think what is tripping me up is the status in front that is making it a little more difficult for me access the different locations.
I am following this tutorial that seems pretty clear but haven't gotten it to work on my end yet. https://www.youtube.com/watch?v=XssLaKDRV4Y
The below code is part of my Service class and it works in getting the expected http response (mentioned above) and getting the success message. When I uncomment the few lines of code below my app breaks and doesn't store any objects to a list.
public async Task<string> GetLocationData()
{
var user_id = Convert.ToString(App.Current.Properties["user_id"]);
var session = Convert.ToString(App.Current.Properties["session"]);
var key = "randomkeystring";
var body = new List<KeyValuePair<string, string>>();
body.Add(new KeyValuePair<string, string>("user_id", user_id));
body.Add(new KeyValuePair<string, string>("session", session));
body.Add(new KeyValuePair<string, string>("key", key));
try
{
using (var client = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Post, "apiurl/api/something") { Content = new FormUrlEncodedContent(body) };
var result = await client.SendAsync(request);
if (!result.IsSuccessStatusCode)
{
return "false";
}
//string representation
var stringResponseFromServer = await result.Content.ReadAsStringAsync();
//convert JSON to series of objects
//LocationCollection locationCollection = JsonConvert.DeserializeObject<LocationCollection>(stringResponseFromServer);
//System.Diagnostics.Debug.WriteLine(locationCollection.locations.Count);
var response = JsonConvert
.DeserializeObject<GetLocationDataResponse>(stringResponseFromServer);
if (response == null) return "false";
jsonString.HttpGetLocationDataString += stringResponseFromServer;
return stringResponseFromServer;
}
}
catch
{
return "false";
}
}
My locations.cs looks like this
public class Locations
{
public int id { get; set; }
public string name { get; set; }
public string contact_first_name { get; set; }
public string contact_last_name { get; set; }
public string contact_email { get; set; }
public string contact_phone_number { get; set; }
public string billing_address { get; set; }
public string billing_city { get; set; }
public string billing_state { get; set; }
public string billing_zip { get; set; }
public string traps { get; set; }
}
Then I have a LocationCollection.cs where i hope to store the different locations so I can loop through them later and do whatever I need to do to them.
public class LocationCollection
{
public List<Locations> locations { get; set; }
}
And then I call the method on my MainPage after the user logs in
insectService.GetLocationData().ContinueWith(async (task) =>
{
var getLocationDataResponse = JsonConvert.DeserializeObject<GetLocationDataResponse>(task.Result);
if (getLocationDataResponse.status == "failure")
{
await DisplayAlert("Location Data Failure", "Could not retrieve data", "Try Again");
await Navigation.PushModalAsync(new LoginPage(), true);
}
//System.Diagnostics.Debug.WriteLine(getLocationDataResponse.locations.ToString());
if (getLocationDataResponse.status == "success")
{
await DisplayAlert("Location Data Success", "Successfully Recovered Data", "Back to Main Page");
}
}); //TaskScheduler.FromCurrentSynchronizationContext());
Right now I am able to get the expect JSON string of {\"status\":\"success\",\"locations\":[{\"id\":\"24\",\"name\":\"Test New Location Test\",\"contact_first_name\":\"Test\",\"contact_last_name\":\"Test\",\"contact_email\":\"test#email.com\",\"contact_phone_number\":\"(555) 555-5555\",\"billing_address\":\"Test\",\"billing_city\":\"Test\",\"billing_state\":\"AK\",\"billing_zip\":\"55555\",\"traps\":[]}]} and am able to check if the status is success or failure. However I am having trouble storing the different parts of "locations" into a list. Any suggestions?
You can give a try deserilizing your api result in to a result model, then from there again de serialize to location model. Example:
My API Model
public class ApiResult
{
public Int32 Status { get; set; }
public string Message { get; set; }
public string Data { get; set; }
}
Inside Data I copy all my return result from API, then Deserialize to exact Model. Here is the example:
public static List<Models.OrderList> RetrieveOrderList(string host, List<Models.FilterCondition> filter)
{
string sResult = HttpHelper.httpPost(host + "api/Order/RetrieveOrderList", Newtonsoft.Json.JsonConvert.SerializeObject(filter));
Models.ApiResult mResult = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.ApiResult>(sResult);
if (mResult.Status == 0)
throw new Exception(mResult.Message);
return Newtonsoft.Json.JsonConvert.DeserializeObject<List<Models.OrderList>>(mResult.Data);
}
If you see the above My return result(string), I deserialize to API result Model, then again finally deserialize to OrderList Model. Hope this help to sort out your issue.
Update: API Controller
I forgot to mention one more point. On the API Controller Side Your result need to copied to API Model.
Here is the Example
[HttpPost]
public Models.ApiResult RetrieveOrderList(List<Models.FilterCondition> conditions)
{
Models.ApiResult mResult = new Models.ApiResult();
try
{
List<Models.OrderList>mOrderList= BLL.Order.RetrieveOrderList(conditions);
mResult.Status = 1;
mResult.Message = "Success";
mResult.Data = Newtonsoft.Json.JsonConvert.SerializeObject(mOrderList);
return mResult;
}
catch (Exception ex)
{
mResult.Status = 0;
mResult.Message = ex.Message;
mResult.Data = "";
return mResult;
}
}
My locations model didn't match the JSON response. Once I read what the exception was in my catch statement I saw that 'traps' was supposed to be another list. After I changed traps property to a List and then made another class for 'traps' everything worked fine.

How to Parse Json from UrI to list on Xamarin Android

I tried too many but no success
this is my method to get JSON string from web service Uri and deserialize it to list, and I want to use it on Xamarin Android App
public async void DownloadDataAsync()
{
string url = "http://myWebSite.com/jWebService.asmx/GetOffersJSON?storeID=2";
var httpClient = new HttpClient();
Task <string> downloadTask = httpClient.GetStringAsync(url);
string content = await downloadTask;
// de-serializing json response into list
JObject jsonResponse = JObject.Parse(content);
IList<JToken> results = jsonResponse["offs"].ToList();
foreach (JToken token in results)
{
offers poi = JsonConvert.DeserializeObject<offers>(token.ToString());
offs.Add(poi);
}
}
when I call DownloadDataAsync(); I get an error:
An unhandled exception occured.
what is the solution?
I've parameter on my web service method, who can I deal with it?
Here is my JSON Uri result:
This XML file does not appear to have any style information associated with
it. The document tree is shown below.
<string xmlns="http://tempuri.org/">[{"ItemID":20,"ItemBarcode":"111","ItemName":"hgh","ItemImage":"MegaOrders22017-04-14-08-34-27.jpg","ItemPrice":7.0000,"ItemNotes":"gffgdfj","OfferOn":true},{"ItemID":21,"ItemBarcode":"222","ItemName":"Nod","ItemImage":"MegaOrders22017-04-14-08-34-57.jpg","ItemPrice":4.0000,"ItemNotes":"kkkkkk","OfferOn":true},{"ItemID":22,"ItemBarcode":"333","ItemName":"kjkjkjkj","ItemImage":"MegaOrders22017-04-14-08-35-21.jpg","ItemPrice":6.0000,"ItemNotes":"hhhhggggg","OfferOn":true},{"ItemID":23,"ItemBarcode":"4444","ItemName":"oioioio","ItemImage":"MegaOrders22017-04-14-08-35-50.jpg","ItemPrice":5.0000,"ItemNotes":"hjhgfdfghj","OfferOn":true}]
</string>
the Class I used:
public class offers
{
public int ItemID { get; set; }
public string ItemBarcode { get; set; }
public string ItemName { get; set; }
public string ItemImage { get; set; }
public double ItemPrice { get; set; }
public string ItemNotes { get; set; }
public bool OfferOn { get; set; }
}
Please try this:
public async void DownloadDataAsync()
{
try
{
string url = "http://myWebSite.com/jWebService.asmx/GetOffersJSON?storeID=2";
var httpClient = new HttpClient();
var content = await httpClient.GetStringAsync(url);
// de-serializing json response into list, with filtering before
var startPosition = content.IndexOf('>') + 1;
var endPosition = content.LastIndexOf("</", StringComparison.Ordinal);
var filteredResponseCharArray = new char[endPosition - startPosition];
content.CopyTo(startPosition, filteredResponseCharArray, 0, endPosition - startPosition);
var listOfOffers = JsonConvert.DeserializeObject<List<offers>>(new string(filteredResponseCharArray));
}
catch (Exception error)
{
Debug.WriteLine(error);
throw;
}
}
You should change your web service to get a valid JSON response without XML structure.

Am getting an error while reading json data received. Am developing a UWP using C# which reads data from json

public class BMIRSProxy
{
static string json_url = string.Format("http://localhost:8081/bmirs_2015/php_scripts/get_staff_members.php");
public async static Task<StaffMember> GetStaffMember()
{
var http = new HttpClient();
var response = await http.GetAsync(json_url);
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(StaffMember));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (StaffMember)serializer.ReadObject(ms);
return data;
}
}
[DataContract]
public class StaffMember
{
[DataMember]
public string first_name { get; set; }
[DataMember]
public string last_name { get; set; }
[DataMember]
public string title { get; set; }
[DataMember]
public string profile { get; set; }
[DataMember]
public string image_uri { get; set; }
}
Above is the class I created. but when I can the method GetStaffMember within a button created , no data is output. when I debugged I got two errors from the MemomryStream instance ms as below :
List item
ReadTimeout = 'ms.ReadTimeout' threw an exception of type
'System.InvalidOperationException'
List item
WriteTimeout = 'ms.WriteTimeout' threw an exception of type
'System.InvalidOperationException'
Below is the code i used to call the method GetStaffMember
private async void Button_Click(object sender, RoutedEventArgs e)
{
StaffMember myStaffMember = await BMIRSProxy.GetStaffMember();
}
Your help will be highly appreciated because am stuck now
Looks like your JSON string is an array containing 1 element.
So let us deserialize as an array and select the only element for your data binding
public async static Task<StaffMember> GetStaffMemberAsync()
{
var http = new HttpClient();
var response = await http.GetAsync(json_url);
var result = await response.Content.ReadAsStringAsync();
var data = (JsonConvert.DeserializeObject<List<StaffMember>>(result))[0];
return data;
}

How to get JSON String value?

var responseFromServer =
// lines split for readability
"{\"flag\":true,\"message\":\"\",\"result\":{\"ServicePermission\":true,"
+ "\"UserGroupPermission\":true}}";
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var responseValue = serializer.DeserializeObject(responseFromServer);
responseFromServer value is get a webservice, and then how to get the JSON string value, such as "flag","Servicepermission"??
affix: i'm sorry, using c# to do this.
Note: The JavaScriptSerializer is actually the slowest JSON Serializer I've ever benchmarked. So much so I've had to remove it from my benchmarks because it was taking too long (>100x slower).
Anyway this easily solved using ServiceStack.Text's JSON Serializer:
var response = JsonSerializer.DeserializeFromString<Dictionary<string,string>>(responseFromServer);
var permissions = JsonSerializer.DeserializeFromString<Dictionary<string,string>>(response["result"]);
Console.WriteLine(response["flag"] + ":" + permissions["ServicePermission"]);
For completeness this would also work with ServiceStack.Text.JsonSerializer:
public class Response
{
public bool flag { get; set; }
public string message { get; set; }
public Permisions result { get; set; }
}
public class Permisions
{
public bool ServicePermission { get; set; }
public bool UserGroupPermission { get; set; }
}
var response = JsonSerializer.DeserializeFromString<Response>(responseFromServer);
Console.WriteLine(response.flag + ":" + response.result.ServicePermission);
if u are using jQuery u can do this
var json=jQuery.parseJSON(responseFromServer);
//acess
alert(json.ServicePermission);
if you are asing microsoft ajax do this
var json=Sys.Serialization.JavaScriptSerializer.deserialize(responseFromServer,true);
//acess
alert(json.ServicePermission);
in c# like php i have'nt seen any method that converts json to object on the fly. To do conversions in c# you must first create a class for this.
For your case you can do like this
//define classes
public class Response
{
public bool flag { get; set; }
public string message { get; set; }
public Permisions result { get; set; }
}
public class Permisions
{
public bool ServicePermission { get; set; }
public bool UserGroupPermission { get; set; }
}
var responseFromServer =
// lines split for readability
"{\"flag\":true,\"message\":\"\",\"result\":{\"ServicePermission\":true,"
+ "\"UserGroupPermission\":true}}";
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var responseValue = serializer.Deserialize<Response>(responseFromServer);
//access
responseValue.result.ServicePermission

Categories