Get certain value from JSON string - c#

I have the following code which gets me the entire JSON string; however, I want to get just the cashprice for this.
string url = "http://ondemand.websol.barchart.com/getGrainBids.json?apikey=12345&location=54943&commodityName=Corn%20(%232%20Yellow)&bidsPerCom=2";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader responseReader = new StreamReader(responseStream))
{
string json = responseReader.ReadToEnd();
string data = JObject.Parse(json)["bids/price"].ToString();
Label1.Text = data;
}
}
The part I have commented out is what I want to work but each time I try that it returns just a null value. This is the JSON string that shows when the reader runs:
{
"status": {
"code": 200,
"message": "Success."
},
"results": [
{
"bids": [
{
"id": "19699878",
"commodity": "CORN",
"symbol": "ZCH19",
"delivery_start": "2019-03-01 00:00:00",
"delivery_end": "2019-03-31 23:59:59",
"basis": "-35.00",
"notes": null,
"active": true,
"sym_root": "ZC",
"commodity_id": "119555",
"customer_commodity_id": "5813",
"commodity_display_name": "Corn (#2 Yellow)",
"unitvalue": 1,
"unitweight": 56,
"deliveryMonth": "Mar19",
"deliveryYear": "2019",
"basismonth": "Mar 2019",
"timestamp": 1544543949,
"as_of": "09:59",
"price": "3.48",
"pricecwt": "6.205357",
"basiscwt": -62.5,
"pricetonne": "136.804545",
"basistonne": -1377.8875,
"change": "-0.015",
"rawchange": -0.015,
"pctchange": "-0.43",
"cashprice": "3.48",
"cashpricetonne": "136.804545",
"delivery_sort": "2019-03-01 00:00:00",
"delivery_start_raw": "2019-03-01 00:00:00",
"delivery_end_raw": "2019-03-31 23:59:59",
"basisSymbol": "ZCBH19-54943-5813.CM",
"cashPriceSymbol": "ZCPH19-54943-5813.CM"
},
{
"id": "14938531",
"commodity": "CORN",
"symbol": "ZCZ19",
"delivery_start": "2019-12-01 00:00:00",
"delivery_end": "2019-12-31 23:59:59",
"basis": "-45.00",
"notes": null,
"active": true,
"sym_root": "ZC",
"commodity_id": "119555",
"customer_commodity_id": "5813",
"commodity_display_name": "Corn (#2 Yellow)",
"unitvalue": 1,
"unitweight": 56,
"deliveryMonth": "Dec19",
"deliveryYear": "2019",
"basismonth": "Dec 2019",
"timestamp": 1544543947,
"as_of": "09:59",
"price": "3.56",
"pricecwt": "6.361607",
"basiscwt": -80.3571428571,
"pricetonne": "140.249263",
"basistonne": -1771.56964286,
"change": "-0.01",
"rawchange": -0.01,
"pctchange": "-0.28",
"cashprice": "3.56",
"cashpricetonne": "140.249263",
"delivery_sort": "2019-12-01 00:00:00",
"delivery_start_raw": "2019-12-01 00:00:00",
"delivery_end_raw": "2019-12-31 23:59:59",
"basisSymbol": "ZCBZ19-54943-5813.CM",
"cashPriceSymbol": "ZCPZ19-54943-5813.CM"
}
],
"distance": null,
"company": "Ag Partners",
"locationId": 54943,
"location": "Brown/Sab/Rulo/WC",
"facility_type": "Country Elevator",
"address": "2750 Acorn Rd",
"city": "Sabetha",
"state": "KS",
"lng": -95.786193,
"lat": 39.9061537,
"phone": "785-284-2185",
"url": "www.agpartnerscoop.com",
"zip": "66534",
"county": "Nemaha County",
"basisTimestamp": "2018-12-11T09:02:48-06:00"
}
]
}
Any suggestions how to get the 3.48 show correctly? I'm sure it's something small I'm missing.

There are multiple bids in the JSON. If you just want to get the first one, you can use SelectToken and supply a path like this:
JObject jo = JObject.Parse(json);
string cashPrice = (string)jo.SelectToken("results[0].bids[0].cashprice");
Label1.Text = cashPrice;
Fiddle: https://dotnetfiddle.net/rUklUq
If you want to get prices for all bids, you can use SelectTokens and use a wildcard like this:
JObject jo = JObject.Parse(json);
List<string> allPrices = jo.SelectTokens("results[0].bids[*].cashprice")
.Values<string>()
.ToList();
Fiddle: https://dotnetfiddle.net/lGbJEe

For things like this we like to use JsonPaths. Here is our go to references if you want to try that way. http://jsonpath.com/ and https://goessner.net/articles/JsonPath/index.html#e2
var data = JObject.Parse(json).SelectTokens("$.results[*].bids[*].price");
var result = data;

You need to convert the Json string into a Json Object and get the results array.
JSONObject jsonObject = new JSONObject(jsonString);
Once you have the Json Object you need to get the results[] and loop through it to get the Bids[] and in there you can get cashprice.

Brian had the perfect answer:
JObject jo = JObject.Parse(json);
string cashPrice = (string)jo.SelectToken("results[0].bids[0].cashprice");
Label1.Text = cashPrice;

Related

How to verify the list of keys are present in the Json?

In my API testing I am using Jcontainer to Convert response to Json.
Ex:
[Test]
public void GetUsersList()
{
var response = us.UserList();
JContainer jsonresponse = rh.ConvertResponseToJson(response);
}
I am trying to the following validation against the Json
Verify if all Keys are present (If all keys in json are present, like id, timestamp, type etc..)
Here is my json
[
{
"id": "aa0db615-d4cb-4466-bc23-0e0083002330",
"timestamp": "2020-02-11T19:00:00-05:00",
"type": 33554432,
"info": "Full Synchronization request for all endpoints",
"schedule": "once",
"lastRun": null,
"flags": 6,
"creator": null,
"isEditable": true,
"location": 0,
"duration": null
},
{
"id": "70baa28c-e270-447b-b88a-20d30a9542db",
"timestamp": "2020-02-11T19:00:00-05:00",
"type": 33554432,
"info": "Full Synchronization request for all endpoints",
"schedule": "once",
"lastRun": null,
"flags": 6,
"creator": null,
"isEditable": true,
"location": 0,
"duration": null
}
]
Here is my Convert respone to Json for reference
public JContainer ConvertResponseToJson(HttpWebResponse response)
{
string localString;
if (response.ContentEncoding.Contains("application/xml"))
{
// Convert the escaped Stream into an XML document.
ConfigXmlDocument xmlDocument = new ConfigXmlDocument();
xmlDocument.LoadXml(ConvertResponseStreamToString(response));
// Now convert the properly-escaped JSON for the response into a JContainer
localString = JsonConvert.SerializeXmlNode(xmlDocument);
}
else
localString = ConvertResponseStreamToString(response);
return JToken.Parse(localString) as JContainer;
}
For now I created a model of the Json to read it by array index. But I am doing mutiple assetions to vaidate all keys. I want to just loop through them. Here is what i have so far
var response = us.UserList();
JContainer jsonresponse = rh.ConvertResponseToJson(response);
var castedModel = Jsonresponse.ToObject<IList<Model>>();
Assert.IsNotNull(castedModel[0].info); //This is repeated I am trying to avoid this
Assert.IsNotNull(castedModel[0].task);
Assert.IsNotNull(castedModel[0].timestamp)
You could just use a for loop.
var castedModel = Jsonresponse.ToObject<IList<Model>>();
for(int i = 0; i < castedModel.Count; i++)
{
Assert.IsNotNull(castedModel[i].info);
Assert.IsNotNull(castedModel[i].task);
Assert.IsNotNull(castedModel[i].timestamp)
{

Add a field into JSON array

I got a JSON string with an array like this:
{
"Id": 123,
"Username": "Sr. X",
"Packages": [
{
"Name": "Cups",
"SupplierId": 1,
"ProviderGroupId": 575,
"SupplierName": "Foo Cups"
},
{
"Name": "Pins",
"SupplierId": 5,
"ProviderGroupId": 1082,
"SupplierName": "Foo Pins"
}
]
}
and I want to add a new field into Packages array like:
"Packages": [
{
"Name": "Cups",
"SupplierId": 1,
"ProviderGroupId": 575,
"SupplierName": "Foo Cups",
"New Field": "Value"
},...
Right now I can add a new field but in the main object, I'm using Json.NET library to do the job, but it seems that the documentation doesn't reach that level.
Have any one of you done it before?
JObject implemets IDictionary.
var jObj = JObject.Parse(json);
foreach(var item in jObj["Packages"])
{
item["New Field"] = "Value";
}
var newjson = jObj.ToString(Newtonsoft.Json.Formatting.Indented);
Try
JObject root = (JObject) JsonConvert.DeserializeObject(File.ReadAllText("products.json"));
JArray packages = (JArray) root["Packages"];
JObject newItem = new JObject();
newItem["Name"] = "Cups";
// ...
packages.Add(newItem);
Console.WriteLine(root); // Prints new json

c# to query a json file

I have a json file as such:
{
"rowId": "39",
"refNumber": "19",
"title": "Mobile",
"date": "10/29/2015",
"status": "saved"
}{
"rowId": "10",
"refNumber": "478",
"title": "Completion",
"date": "10/30/2015",
"status": "saved"
}{
"rowId": "11",
"refNumber": "604",
"title": "Online Order",
"date": "10/30/2015",
"status": "failed"
}
What I'd like to do is query the json file in c# like as such with a winforms app:
string qrySaved = "select count(*) as total from file where status = 'saved'";
string qryFailed = "select count(*) as total from file where status = 'failed'";
Then place the results in two variables.
I did the following:
logFolder = Directory.GetCurrentDirectory();
logFolder = logFolder.Replace("\\bin\\Debug", "\\metrics");
logFile = logFolder + #"\log.json";
I'm using the Newtonsoft.Json nuget resource and know how to read the first object but can't figure out how to query the file to return total counts based on a given element.
You can try something like this:
static void Main(string[] args)
{
string json = File.ReadAllText("sample1.json");
var array = JArray.Parse(json);
int savedcount = array.Count(i => i["status"].Value<string>() == "saved");
int failedcount = array.Count(i => i["status"].Value<string>() == "failed");
}
Might a typo but the JSON posted was invalid so I changed it as below to make it work:
[
{
"rowId": "39",
"refNumber": "19",
"title": "Mobile",
"date": "10/29/2015",
"status": "saved"
},
{
"rowId": "10",
"refNumber": "478",
"title": "Completion",
"date": "10/30/2015",
"status": "saved"
},
{
"rowId": "11",
"refNumber": "604",
"title": "Online Order",
"date": "10/30/2015",
"status": "failed"
}
]

how to read the json response from my response httpwebreponse

This is my sample string
{
"aaa": "0",
"nnn": "Ok",
"rrr": [
{
"id": "0",
"name": "Reserved",
"desc": "Reserved",
"shortdesc": "",
"price": "07.80",
"isvariableprice": "0",
"taxcategoryid": "0",
"istaxinclusive": "0",
"brandid": "1",
"isnetsalesexempt": "0",
"itemtype": "0",
"skus": [],
"modifiergroups": [],
"prices": [],
"pricerules": [],
"categories": [],
"nutrition": [
{
"id": "1",
"amount": "10.0000"
}
]
}
]
}
I want to only retrieve "id" and "price" from the sample json response. The JSON is more that this and have multiple id;s and prices ... how do I put a loop to retrieve all those in an array. Please help.
This is where I am right now.
if (response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
Console.WriteLine("Response stream received.");
string resultString = readStream.ReadToEnd();
//var ser = new DataContractJsonSerializer(typeof(RootObject));
var stream = new MemoryStream(Encoding.Unicode.GetBytes(resultString));
dynamic data = JsonObject.Parse(resultString);
Console.WriteLine(data.id); //??????????
readStream.Close();
}
this code gives me above string in "data" but I want to pull "id" and "price"
thx in advance all you gurus
Json.Net will make your life easier when working with JSON http://json.codeplex.com/
With Json.Net in place.
You can do this in a dynamic fashion or in a strongly typed fashion.
dynamic:
var dynJson = JsonConvert.DeserializeObject<dynamic>(yourJsonString);
//for simple values
Console.WriteLine(dynJson.aaa);
Console.WriteLine(dynJson.nnn);
//for list values
foreach(var r in dynJson.rrr){
//for simple values in rrr
Console.WriteLine(r.id);
//for list values in rrr
foreach(var price in rrr.prices)
Console.WriteLine(price)
}

Deserialize GET response

How do I deserialize this text. I tried with JSON but I get "Invalid JSON primitive" error.
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 1
},
"objects": [
{
"blocked": false,
"groups": [],
"id": "1111",
"name": "John Doe",
"number": "+15555555555",
"resource_uri": "/api/v1/contacts/1111/"
}
]
}
This is the code I used:
var jss = new JavaScriptSerializer();
var dictionary = jss.Deserialize<Dictionary<string, string>>(buffer.ToString());
Easy to Fix. Deserialize to <Dictionary<string, object> instead of <Dictionary<string, string>
var dictionary = jss.Deserialize<Dictionary<string, object>>(buffer.ToString());
Full test code
string json = #"{
""meta"": {
""limit"": 20,
""next"": null,
""offset"": 0,
""previous"": null,
""total_count"": 1
},
""objects"": [
{
""blocked"": false,
""groups"": [],
""id"": ""1111"",
""name"": ""John Doe"",
""number"": ""+15555555555"",
""resource_uri"": ""/api/v1/contacts/1111/""
}
]
}";
var jss = new JavaScriptSerializer();
var dictionary = jss.Deserialize<Dictionary<string, object>>(json);

Categories