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";
Related
For example we have following document in elastic:
{
"name": "Bob",
"age": "22",
"phrase": "ohohoho",
"date": "2022-10-20T00:00:00Z"
}
string phrase ;
DateTime? date;
Then we want put following:
{
"name": "not Bob",
"age": "22",
"phrase": null,
"date": null
}
in c#:
var updateRequest = new UpdateRequest<T, T>(entity)
{
ScriptedUpsert = true,
Script = new InlineScript(
$"if (someCondition) {{ctx._source.putAll(params.entity);}} else {{ctx.op = \"noop\";}}")
{
Lang = "painless",
Params = new Dictionary<string, object>() { { "entity", entity } },
},
Upsert = Activator.CreateInstance<T>()
};
but in the end it will not update phrase and date.
It makes following request:
POST /myIndex/_update/b90278fd-1a66-40bf-b775-d076122c6c02
{
"script": {
"source": ""if (someCondition) {{ctx._source.putAll(params.entity);}} else {{ctx.op = \"noop\";}}"",
"lang": "painless",
"params": {
"entity": {
"name": "",
"age": 22
}
}
},
"upsert": {
"age": 0
}
}
Idk why but it skips all fields with null.
How to update nullable fields to null?
NEST does not support sending null values by default.
You can have a check in script such that if a value is not passed then you can remove it from document.
var updateRequest = new UpdateRequest<T, T(entity)
{
ScriptedUpsert = true,
Script = new InlineScript($"if (params.entity.phrase==null)ctx._source.remove('phrase');")
{
Lang = "painless",
Params = new Dictionary<string, object>() { { "entity", entity } },
},
Upsert = Activator.CreateInstance<T>()
};
You can check for more details here
I'm reading my json file from and trying to replace the property values. JSON file is below.
{
"fields": {
"summary": "summaryValue",
"project": {
"key": "projectValue"
},
"priority": {
"name": "priorityValue"
},
"Requestor": {
"name": "RequestorValue"
},
"issue": {
"name": "issueValue"
},
"labels": "LabelValue",
"customfield_xyz": "customfield_xyzValue"
}
}
How can I replace the value for each item inside the fields property ?
for ex:
{"fields": {
"summary": "NewsummaryValue",
"project": {
"key": "NewprojectValue"
},
"priority": {
"name": "NewpriorityValue"
}
}
}
Below is the code to parse my json file,
StreamReader r = new StreamReader(filepath);
var jsondata = r.ReadToEnd();
var jobj = JObject.Parse(jsondata);
foreach (var item in jobj.Properties())
{
\\replace code
}
I do not know exactly what you want. But I changed the json information in the code snippet as you wanted.
dynamic dataCollection = JsonConvert.DeserializeObject<dynamic>(jsonData);
string summary = dataCollection["fields"]["summary"];
string project = dataCollection["fields"]["project"]["key"];
string priority = dataCollection["fields"]["priority"]["name"];
dynamic json = new JObject();
json.summary = summary;
json.project = project;
json.priority = priority;
dynamic jsonRoot = new JObject();
jsonRoot.fields = json;
Console.WriteLine(jsonRoot.ToString());
output:
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)
{
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;
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)
}