cannot access child value Newtonsoft Json - c#

I want to parse following string , bellow is my code , and below is my string
string jsn = Convert.ToString(
#"{
'TaxProfile':{'id':258658,'IncomeTypeStatus':[{'IncomeType':'0001','StatusCodeDesc':'Ready For SAP','StatusCode':'RFS','PayFromCountryCode':'IE'}],'ExpirationDate':null,'FormName':null},
'ErrorJSON':'[{\'TypeID\':\'Z_FI_MDG\',\'SeverityCode\':\'3\',\'Note\':\'\\\'An Electronic Fund Transactions (EFT) routing number is comprised of a three-digit financial institution number and a five-digit branch number, preceded by a \\\\\\\'leading zero\\\\\\\'. \\\\\\\\r\\\\\\\\n•YYY: Institution\'}]'
}"
);
JObject jo = JObject.Parse(jsn);
// dynamic jo = JObject.Parse(jsn);
TenantPayeeMessage apTenantMessage = null;
// JObject jo = o;
// var auditObject = jo.ToString();
JToken PartnerReferenceId;
string Payeeid, PayeeStatus, bpid = string.Empty;
JToken[] items = null;
JToken sectionStatus = null;
JToken TaxIncomType = null;
JToken[] bank = null;
var bankJson = new Dictionary<string, string>();
JToken ErrorJSONSeverityNote,
ErrorJSONSeverityCode,
ErrorJSONTypID,
BasicErrorJSON,
Basicbpid,
Basicstatus,
BasicId, CompliancebpErrorJSON,
Compliancebpid, Compliancestatus, ComplianceId, ErrorJSONpp,
bbpidpp, statuspp,
PaymentProfileId, FormName,
ExpirationDate,
PayFromCountryCode, StatusCode, StatusCodeDesc, IncomeType, TaxProfileId;
//Guid SyncIdentifier = Guid.Parse(jo["BusinessPartnerSUITEBulkReplicateConfirmation"]["BusinessPartnerSUITEReplicateConfirmationMessage"]["MessageHeader"]["UUID"].Value<string>());
if (null != jo["TaxProfile"]["id"] && null != jo["TaxProfile"]["id"])
{
TaxProfileId = jo["TaxProfile"]["id"].Value<string>();
}
TaxIncomType = jo["TaxProfile"]["id"]["IncomeTypeStatus"].Value<string>();
in last line i get error
Cannot access child value on Newtonsoft.Json.Linq.JValue.
I am not sure where i am going wrong i want to parse above string

Your code looks like (I've removed code not related to exception and formatted JSON string):
var jsn = Convert.ToString(
#"{
'TaxProfile': {
'id': 258658,
'IncomeTypeStatus': [
{
'IncomeType': '0001',
'StatusCodeDesc': 'Ready For SAP',
'StatusCode': 'RFS',
'PayFromCountryCode': 'IE'
}
],
'ExpirationDate': null,
'FormName': null
},
'ErrorJSON': '[{\'TypeID\':\'Z_FI_MDG\',\'SeverityCode\':\'3\',\'Note\':\'\\\'An Electronic Fund Transactions (EFT) routing number is comprised of a three-digit financial institution number and a five-digit branch number, preceded by a \\\\\\\'leading zero\\\\\\\'. \\\\\\\\r\\\\\\\\n•YYY: Institution\'}]'
}");
var jo = JObject.Parse(jsn);
var TaxIncomType = jo["TaxProfile"]["id"]["IncomeTypeStatus"].Value<string>();
Code
jo["TaxProfile"]["id"]
returns 258658. So, if you try to get IncomeTypeStatus property of it, you'll get above mentioned exception. Probably you need to remove id from your call chain.
jo["TaxProfile"]["IncomeTypeStatus"]

Related

I can´t find the track and trace number in my json string

I can´t find a value in a json string using json.net
I´ve tried jsonstr[0].track_numbers[0].track_number
This is my json file.
{
"0": {
"increment_id": "112",
"track_numbers": [
{
"track_number": "2223",
"title": "tit",
"carrier_code": "custom"
}
]
},
"live_shipping_status": "Delivered"
}
I want to find the Track_nummber.
dynamic jsonstr = JsonConvert.DeserializeObject(json));
var track = jsonstr[0].track_numbers[0].track_number
(donsent work)
The 0 of your json is a string key, not an index position:
dynamic obj = JsonConvert.DeserializeObject(json);
var trackNumber = obj["0"].track_numbers[0].track_number;
Note the difference in getting the first entry of track_numbers, which is an array.

Unable to update JToken value

I'm trying to update the value of JToken but its reference is not getting updated.
JSON string:
{
"Title": "master",
"Presentation": [
{
"Component": {
"Content": {
"Title": "Set New Title",
}
}
}
]
}
and the usage is given below
JObject jo = JObject.Parse(File.ReadAllText(file.json));
foreach (var token in jo.SelectTokens("$..Component.Content").Children())
{
JProperty prop = token.ToObject<JProperty>();
prop.Value = "New Title";
}
string jsonText = JsonConvert.SerializeObject(jo, Formatting.Indented);
In this example, I'm trying to update the value of Title property. It is getting updated within foreach, means local variable is getting updated but changes are not reflecting in main jobject.
Can anyone help me if i'm doing anything wrong?
Once you call ToObject then you are working with a copy.
If instead you try this, it should work:
JObject jo = JObject.Parse(File.ReadAllText(file.json));
foreach (var prop in jo.SelectTokens("$..Component.Content")
.Children().OfType<JProperty>())
{
prop.Value = "New Title";
}
string jsonText = JsonConvert.SerializeObject(jo, Formatting.Indented);
or to handle multiple types of JTokens:
JObject jo = JObject.Parse(File.ReadAllText(file.json));
foreach (var token in jo.SelectTokens("$..Component.Content")
.Children())
{
var prop = token as JProperty;
if (prop != null) prop.Value = "New Title";
var array = token as JArray;
if (array != null)
{
// some other logic
}
}
string jsonText = JsonConvert.SerializeObject(jo, Formatting.Indented);
The answer from Stuart may be erroneous because "Content" may contain other children and all of theme could be renamed or their values could be changed.
I've encountered the similar issue.
From the body I needed to remove value, because it was too long for logging and unnecesary, so I needed to change it's value.
I could've changed it with indexer like token["name"], but "name" could be of different cases, so I needed an universal case independent way to erase it's value:
And I implemented it other way:
var jObject = JObject.Parse(body);
JToken token;
if (jObject.TryGetValue(
Constants.FieldName,
StringComparison.InvariantCultureIgnoreCase,
out token))
{
var jProperty = token.Parent as JProperty;
if (jProperty != null)
{
jProperty.Value = "removed";
}
body = jObject.ToString(Formatting.Indented);
}
Here you have a magnificient example of how you can do this, in a proper way. Both solutions above didn't work for me, but this very simple yes. Simply work with the JToken or Object as an array. That's all.
https://www.newtonsoft.com/json/help/html/ModifyJson.htm

Can't deserialize an object using Newtonsoft.Json.Linq;

I receive a string in this format:
{
"ok": true,
"quote": { // the below is the same as returned through the REST quote API
"symbol": "FAC",
"venue": "OGEX",
"bid": 5100, // best price currently bid for the stock
"ask": 5125, // best price currently offered for the stock
"bidSize": 392, // aggregate size of all orders at the best bid
"askSize": 711, // aggregate size of all orders at the best ask
"bidDepth": 2748, // aggregate size of *all bids*
"askDepth": 2237, // aggregate size of *all asks*
"last": 5125, // price of last trade
"lastSize": 52, // quantity of last trade
"lastTrade": "2015-07-13T05:38:17.33640392Z", // timestamp of last trade,
"quoteTime": "2015-07-13T05:38:17.33640392Z" // server ts of quote generation
}
}
I want to use the Newtonsoft.Json.Linq way of deserializing for performance reasons. When I try to turn the Json string into a Quote object using the following method:
public static Quote QuoteFromJson(string quoteJson)
{
var json = JObject.Parse(quoteJson);
var quote = json["quote"].
Select(q => new Quote
{
Ask = int.Parse(q["ask"].ToString()),
AskDepth = int.Parse(q["askDepth"].ToString()),
AskSize = int.Parse(q["askSize"].ToString()),
Bid = int.Parse(q["bid"].ToString()),
BidDepth = int.Parse(q["bidDepth"].ToString()),
BidSize = int.Parse(q["bidSize"].ToString()),
Last = int.Parse(q["last"].ToString()),
LastSize = int.Parse(q["lastSize"].ToString()),
LastTrade = q["lastTrade"].ToString(),
QuoteTime = q["quoteTime"].ToString(),
Symbol = q["symbol"].ToString(),
}).First();
return quote;
}
This gives an error message:
Cannot access child value on Newtonsoft.Json.Linq.JProperty
What am I doing wrong?
Here is a direct answer to your question:
The quote variable corresponds to the quote token in your JSON. This is a single item and not a collection, so you shouldn't treat it as a collection and use the Select method.
Instead, access it directly like this:
var json = JObject.Parse(quoteJson);
var quote = json["quote"];
var result = new Quote
{
Ask = int.Parse(quote["ask"].ToString()),
AskDepth = int.Parse(quote["askDepth"].ToString()),
AskSize = int.Parse(quote["askSize"].ToString()),
Bid = int.Parse(quote["bid"].ToString()),
BidDepth = int.Parse(quote["bidDepth"].ToString()),
BidSize = int.Parse(quote["bidSize"].ToString()),
Last = int.Parse(quote["last"].ToString()),
LastSize = int.Parse(quote["lastSize"].ToString()),
LastTrade = quote["lastTrade"].ToString(),
QuoteTime = quote["quoteTime"].ToString(),
Symbol = quote["symbol"].ToString(),
};
Your problem is that you are iterating through the children of "quote" with your Select, then retrieving their properties by name. This would be appropriate if "quote" were an array, but it's not -- it's already a single object. Thus you should do:
var rootObj = JObject.Parse(quoteJson);
var quoteObj = rootObj["quote"];
var quote = new Quote
{
Ask = (int)quoteObj["ask"],
AskDepth = (int)quoteObj["askDepth"],
AskSize = (int)quoteObj["askSize"],
Bid = (int)quoteObj["bid"],
BidDepth = (int)quoteObj["bidDepth"],
BidSize = (int)quoteObj["bidSize"],
Last = (int)quoteObj["last"],
LastSize = (int)quoteObj["lastSize"],
LastTrade = (string)quoteObj["lastTrade"],
QuoteTime = (string)quoteObj["quoteTime"],
Symbol = (string)quoteObj["symbol"],
};
Note I am using explicit casting. This handles internationalization of numbers in a manner consistent with the JSON standard. int.Parse() parses using localized formatting, which is not guaranteed to be consistent with the standard in all locales.
However, it is much simpler to use deserialization:
var rootObj = JObject.Parse(quoteJson);
var quoteObj = rootObj["quote"];
var quote = quoteObj.ToObject<Quote>();
I suggest you should time this to make sure it really is slower than Linq to JSON.

How to read property names in array from json string?

Here is the list of data I receive, property names are can be different;
{"data":"[
{
"id":"1",
"name":"aa",
"email":"aa#aa.com",
"address":"11"
},
{
"id":"2",
"name":"bb",
"email":"bb#bb.com",
"address":"22"
}
]"}
Here is my c# code
Which I get an error on the 3rd line. Unable to read json data. Check the url you typed.Invalid cast from 'System.String' to 'Newtonsoft.Json.Linq.JObject'.
var jsonStr = wc.DownloadString(url);
JToken outer = JToken.Parse(jsonStr);
JObject inner = outer["data"].Value<JObject>();
List<string> keys = inner.Properties().Select(p => p.Name).ToList();
How can my output be like this;
id
name
emal
address
It would be great if I also consider n level array such as address > street and address > postcode
Many thanks.
var jObj = JObject.Parse(json);
var props = jObj["data"][0].Select(x => ((JProperty)x).Name).ToList();
BTW: your json is not correct, it should be something like this
{data:[
{ "id":"1",
"name":"aa",
"email":"aa#aa.com",
"address":"11"
},
{"id":"2",
"name":"bb",
"email":"bb#bb.com",
"address":"22"
}
]}
See the " after data: in your question

Parse this json string to string array c#

Feels like there is a one-two row solution for what I want to do:
Parse a string like this:
"{\"postalcode\":\"12345\",\"postalcity\":\"SOME-CITY\",\"country\":\"UK\",\"box\":false}"
Into something like this:
string[] result = { "12345", "SOME-CITY", "UK", "false" };
Whats the simplest way to do this?
string json = "{\"postalcode\":\"12345\",\"postalcity\":\"SOME-CITY\",\"country\":\"UK\",\"box\":false}";
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string,object>>(json);
var postalCode = dict["postalcode"];
//Array is also possible
string[] result = dict.Select(kv => kv.Value.ToString()).ToArray();
You could also use newtonsoft : http://james.newtonking.com/pages/json-net.aspx
string json = #"{
""Name"": ""Apple"",
""Expiry"": new Date(1230422400000),
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""
]
}";
JObject o = JObject.Parse(json);
string name = (string)o["Name"];
// Apple
JArray sizes = (JArray)o["Sizes"];
string smallest = (string)sizes[0];
// Small
I found another related post : JSON to string array in C#
Lib : http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
It looks like your input string is a JSON string, for which you can use a JSON deserializer if you want. If not you can use regular-expression along with named-groups as the following:
List<string> values = new List<string>();
List<string> keys= new List<string>();
string pattern = #"\""(?<key>[^\""]+)\""\:\""?(?<value>[^\"",}]+)\""?\,?";
foreach(Match m in Regex.Matches(input, pattern))
{
if (m.Success)
{
values.Add(m.Groups["value"].Value);
keys.Add(m.Groups["key"].Value);
}
}
var result = values.ToArray();
Named groups in regular-expression are indicated by (?<group-name>pattern). In the above pattern we have two named groups: key, and value which can be grabbed from the Match object using the Groups indexer.
You could use JavaScriptSerializer to serialize the json into a dynamic object which would allow you to access the properties via name e.g.
var address = new JavaScriptSerializer().Deserialize<dynamic>(json);
Console.WriteLine(address["postalcode"]);
I just ran into a similar rabbit hole. This helped me with out any other .dll installs. Hope this helps someone.
using System.Text.Json.Nodes;
public static string cSettings = AppDomain.CurrentDomain.BaseDirectory + #"\Application_Settings.json";
public static void Read_JSON()
{
string read = File.ReadAllText(cSettings);
var jsonObject = JsonNode.Parse(read);
var appname = jsonObject["appname"];
MessageBox.Show(appname.ToString());
}
//output: my test app
Application_Settings.json
{
"appname": "my test app",
"version": "1.0.003",
"id": null,
"firstrun": null,
"firstname": "t",
"lastname": "t",
"email": "some#gmail.com",
"cpu1id": "F00A20F10",
"cpu1key": null,
"gamingpc": false
}
Link to where I found this reference.
I'm using Visual Studio 2022 C#

Categories