how to read the json response from my response httpwebreponse - c#

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)
}

Related

ChoETL json to csv with multiple arrays

If I have a sample json like this and I want to use choETL to convert json to csv, how do i write both arrays to one file?
{
"Id": "123456",
"Request": [
{
"firstName": "A",
"lastName": "B",
}
],
"Response": [
{
"SId": "123"
}
]
}
Csv file should be something like
Id,firstName,lastName,SId
123456,A,B,123
Here is how you can produce the expected CSV from the json by using ChoETL
using (var r = ChoJSONReader.LoadText(json)
.WithField("Id")
.WithField("firstName", jsonPath:"Request[0].firstName", isArray:false)
.WithField("lastName", jsonPath:"Request[0].lastName", isArray:false)
.WithField("SId", jsonPath:"Response[0].SId", isArray:false)
)
{
using (var w = new ChoCSVWriter(Console.Out).WithFirstLineHeader())
w.Write(r);
}
Output:
Id,firstName,lastName,SId
123456,A,B,123
Sample fiddle: https://dotnetfiddle.net/CnBX3C
UPDATE:
If the array is dynamic, here is one way to produce the CSV output by Request json array field
Sample JSON:
{
"Id": "123456",
"Request": [
{
"firstName": "A",
"lastName": "B",
},
{
"firstName": "A1",
"lastName": "B1",
}
],
"Response": [
{
"SId": "123"
},
{
"SId": "1234"
}
]
}
Here is the code to parse the json by Request json array field
using (var r = ChoJSONReader.LoadText(json)
.Configure(c => c.FlattenNode = true).Configure(c => c.FlattenByNodeName = "Request")
)
{
using (var w = new ChoCSVWriter(Console.Out).WithFirstLineHeader())
w.Write(r);
}
Output:
Id,Response_0_SId,Response_1_SId,RequestfirstName,RequestlastName
123456,123,1234,A,B
123456,123,1234,A1,B
Sample fiddle: https://dotnetfiddle.net/CnBX3C

Cannot access child node value JSON

I try to get some data nested in JSON, the extendedData.e_ETP["value"] that I get by making a request to an API to create a list with a key LUS_BU with the value of extendedData.e_ETP["value"].
But when I try to access the value I get the error : Cannot access child value on Newtonsoft.Json.Linq.JValue.
When I specify in the uri the id of an item where `extendedData.e_ETP is not null It works.
The thing is I want to put a default value for LUS_BU if its null or use the one from the extendedData.e_ETP if there is one
Here is a part of the c# code :
myUri = new Uri("https://ilucca.net/api/v3/users?dtContractStart=since,1900-01-01&dtContractEnd=until,2100-01-01,null&fields=id,firstName,lastName,employeeNumber,personalAccount,userAxisValues,legalEntityID,mail,dtContractEnd,dtContractStart,manager[name],birthDate,seniorityDate,gender,extendedData.e_ETP,extendedData.e_contracttype");
request = (HttpWebRequest)WebRequest.Create(myUri);
request.Headers["Authorization"] = "ApiKey";
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
s = reader.ReadToEnd();
reader.Close();
response.Close();
rep = JObject.Parse(s);
salaries = rep["data"]["items"].Where(c => (string)c["name"] != "lad" && (int?)c["legalEntityID"] != 10).Select(c => new T_E_LuccaSalarie_LUS()
{
LUS_ETP = (c["extendedData"]["e_ETP"] != null ) ? (string)c["extendedData"]["e_ETP"]["value"] : "1"
}).ToList();
}
catch (WebException ex)
{
string exMessage = ex.Message;
if (ex.Response != null)
{
using (StreamReader responseReader = new StreamReader(ex.Response.GetResponseStream()))
{
exMessage = responseReader.ReadToEnd();
Console.WriteLine(exMessage);
}
}
}
JSON:
{
"header": {
"generated": "2021-01-22T16:12:53.4193558",
"serverTime": 1395,
"queryTime": 169,
"queryCount": 18,
"principal": "API Integration",
"processId": 6956
},
"data": {
"items": [
{
"id": 6,
"firstName": "John",
"lastName": "Doe",
"employeeNumber": "2",
"personalAccount": "Z0",
"userAxisValues_1": {
"id": 10,
"name": "FT04 SALES",
"url": "https://ilucca.net/api/v3/axissections/48"
},
"legalEntityID": 1,
"mail": "random#mail.com",
"dtContractEnd": "2020-01-30T00:00:00",
"dtContractStart": "2000-06-18T00:00:00",
"manager": {
"name": "John Doe"
},
"birthDate": "1959-08-23T00:00:00",
"seniorityDate": "2010-06-18T00:00:00",
"gender": "Female",
"extendedData": {
"e_ETP": null,
"e_contracttype": {
"id": 9556,
"value": 16
}
}
}
]
},
"metadata": null
}
Feel free to ask if you need any specific details or clarification on specific point.
As discussed in the comment if e_ETP is null then it comes as "e_ETP": null in your Json. That scenario represents that the token is type of JValue with value as null. In positive scenario, the e_ETP type is of JObject
Using below code you can validate the type and assign the value of LUS_ETP
LUS_ETP = jObj["data"]["items"][0]["extendedData"]["e_ETP"].GetType() == typeof(JObject)
? jObj["data"]["items"][0]["extendedData"]["e_ETP"]["value"].Value<string>()
: "1";

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)
{

Get certain value from JSON string

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;

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