I am able to read the json file and store it in a JObject variable. I need to check for null values and ignore any segment that has null values. I was thinking of looping through the JObject but I don't know how i can access every segment/ key in the json below.
I think we can loop like this based on another question i saw on here:
foreach (var x in example) //example is the JObject in which json file is stored
{
string name = x.Key;
JToken value = x.Value;
}
But my json doesnt have keys. How do i go in every segment and check if name, description values are not null?
My json is :
{
"lorem ipsum Segment Groups":[
{
"name":"lorem ipsum",
"description":"lorem ipsum",
"segments":[
"Not Enrolled",
"Started Enrollment – Zipcode Lookup",
"Started Enrollment – Passed Flow Step 1",
"Started Enrollment – Passed Flow Step 2"
]
},
{
"name":"lorem ipsum",
"description":"Status Description",
"segments":[
"Moving in next 30 days",
"Moving in next 90 days",
"Not Moving"
]
},
{
"name":"lorem ipsum",
"description":"Interest description",
"segments":[
"Interested - Lots of Time Reading Many Pages",
"Interested - Lots of Time Comparing Products/Prices"
]
}
]
}
Thanks
Here is an example of how to loop through your JSON:
JObject obj = JObject.Parse(json);
JArray segmentGroups = (JArray)obj.Properties().FirstOrDefault()?.Value;
if (segmentGroups != null)
{
foreach (JObject group in segmentGroups.Children<JObject>())
{
string name = (string)group["name"];
string desc = (string)group["description"];
string[] segments = group["segments"]?.ToObject<string[]>();
Console.WriteLine("name: " + (name ?? "(null)"));
Console.WriteLine("description: " + (desc ?? "(null)"));
Console.WriteLine("segments: " + (segments != null ? "\n " + string.Join("\n ", segments) : "(null)"));
Console.WriteLine();
}
}
Fiddle: https://dotnetfiddle.net/kOJzaZ
By knowing the JSON structure, you can use various types with name formatted as JXxx to read the values you want. However here there is one convenient way of selecting the tokens you want by using a json path. That way you can conveniently target the desired set of tokens and continue processing. I'm not so sure about the performance hit with that approach but you may take its trade-off (and if performance does matter, just try benchmarking it first).
The code can be simple like this:
//suppose your example is the loaded JObject
foreach (var group in example.SelectTokens("['lorem ipsum Segment Groups'][*]"))
{
var name = group["name"].Value<string>();
var desc = group["description"].Value<string>();
//check if they are null here ...
}
Note the way we escape keys or paths containing spaces by wrapping it inside ['']. If your key does not need to be escaped, you can use it directly in the path.
This question already has answers here:
Deserialize JSON with C#
(10 answers)
Closed 2 years ago.
I'm trying to extract specific data, in this case "Name" from a JSON file so that I can use it for the rest of my code later.
My current code where I load JSON:
public static void LoadJson()
{
using (StreamReader r = new StreamReader(#"C:\Users\Work\Documents\MyJson.json"))
{
string json = r.ReadToEnd();
var o = JsonConvert.DeserializeObject<JObject>(json);
var h = o.Value<JObject>("Data")
.Value<JArray>("Accounts");
Console.WriteLine(h[0]);
}
}
JSON example:
{
"Data": {
"Accounts": [
{
"Name": "owner",
"Address": "123456"
},
{
"Name": "Lerris",
"Address": "179672"
}
]
}
}
The output I get from my code right now:
JSON length is much longer than the one I posted above, but it was just to make an example.
Question:
How do I obtain and define both "Name" and "Address" value so that I can use them for the rest of my code?
I hope you guys will get what I mean. If I weren't specific enough please just say and I'll try to explain again.
See this section:
Use JsonDocument for access to data
I have very strange json problem . I need to convert UrlQueryString to another standard for elasticsearch . when you look at below you will see that 2 json . I want to change :
FROM "UrlQueryString": "checkinDate: 2020-07-01,checkoutDate: 2020-07-05,room: Y,Y,Y",
TO
"UrlQueryString": {"checkinDate":"2020-07-01","checkoutDate":"2020-07-05","room": "Y,Y,Y"}
How can I do that? I think that I need regex or another options. also I tried many times for this by using replacing and removing.
I have below string json:
{
"LogLevel": "Information",
"CorrelationId": "44160536-a1e9-4a5b-a19d-9e2323ebfa7a",
"UrlMethod": "GET",
"Data": "",
"UrlQueryString": "checkinDate: 2020-07-01,checkoutDate: 2020-07-05,room: Y,Y,Y",
"UrlPath": /xxxx",
"LogSource": "source1",
"LogDate": "2019-12-28T07:39:24.2434156Z",
"Environment": "xxxx"
}
My desired result:
{
"LogLevel": "Information",
"CorrelationId": "44160536-a1e9-4a5b-a19d-9e2323ebfa7a",
"UrlMethod": "GET",
"Data": "",
"UrlQueryString": {"checkinDate":"2020-07-01","checkoutDate":"2020-07-05","room": "Y,Y,Y"},
"UrlPath": "/xxxx",
"LogSource": "source1",
"LogDate": "2019-12-28T07:39:24.2434156Z",
"Environment": "xxxx"
}
important NOTE: Don't forget something. UrlQueryString is not static. It's exactly dynamic.
at the end of the day;
"UrlQueryString": {"Parameter2": "bird"," anyvalue": "fly"}
or
"UrlQueryString": {"Parameter2": "bird"," anyvalue": "fly","Parameter3": "bird"," anyvalue2": "fly"}
{
"LogLevel": "Information",
"CorrelationId": "44160536-a1e9-4a5b-a19d-9e2323ebfa7a",
"UrlMethod": "GET",
"Data": "",
"UrlQueryString": {"Parameter1": "KuÅŸ"," test1": "1577518755769"},
"UrlPath": "/Json/AutoCompleteHotelCallBack",
"LogSource": "xxxrwr",
"LogDate": "2019-12-28T07:39:24.2434156Z",
"Environment": "xx-1"
}
You're probably thinking too complicated.
You could easily get away with just a normal string replacement. And there would be no risk either, unless one of the values could somehow get a value that's the same as a key. Doesn't seem possible though.
Maybe not the most professional solution, but I doubt that's what you're after. Or if you are, my apologies.
So just a few string replacements on that particular row and it's good to be parsed as a json.
Examples:
.Replace("\"checkinDate: ", "{\"checkinDate:\"")
.Replace(",checkoutDate: ", "\",\"checkoutDate\":\"")
UrlQueryString value is not a valid json or something that can be converted to json with standard processes
Issues:
Its a string without curly braces {}.
Its a string with key and value representation without quotes {"key", "value"}
You can try doing Splits on , and : but that would not work as you have , in your values with possibility of an object (JArray or JObject) as a value. {"key": "val,ue"} or {"key": { "key2": "value" } }
ONLY IFF you can be sure that you will have only Keys and string literals for value in that string, you can use the following method to convert that string to a json. {"key": "value", "key2": "val,ue2"}
Convert string to an array containing keys and values in order.
Convert array to Dictionary<string,string> so JsonConvert can convert to object.
public static object ConvertStringToJson (string convertThisToJson)
{
if (string.IsNullOrEmpty(convertThisToJson))
return JsonConvert.DeserializeObject<object>(JsonConvert.SerializeObject("{}"));
string[] splitStr = convertThisToJson.Split(':');
Dictionary<string, string> dict = new Dictionary<string, string>();
string key, value;
// First element will always be Key
key = splitStr[0];
// Everything in the middle will be Value/NextKey pair (not key/Value)
for (int i = 1; i < splitStr.Count() - 1; i++)
{
// You suggested your value could have commas ... thus LastIndexOf
int indexSplit = splitStr[i].LastIndexOf(",");
value = splitStr[i].Substring(0, indexSplit);
dict.Add(key, value.Trim());
key = splitStr[i].Substring(indexSplit + 1);
}
// Last element in its entirety will be value.
value = splitStr[splitStr.Length - 1];
dict.Add(key, value.Trim());
// You can choose to do either of these.
//return JsonConvert.SerializeObject(dict); // Do change the return type if you decide to go with this.
return JsonConvert.DeserializeObject<object>(JsonConvert.SerializeObject(dict));
}
and use it like this
string str = "checkinDate: 2020-07-01,checkoutDate: 2020-07-05,room: Y,Y,Y";
object jsonObj = ConvertStringToJson(str);
Console.WriteLine(jsonObj.ToString()); // Print Json Object
Console.WriteLine(JsonConvert.SerializeObject(jsonObj)); // Print String
Output
// Json Object.
{
"checkinDate": "2020-07-01",
"checkoutDate": "2020-07-05",
"room": "Y,Y,Y"
}
// String
{"checkinDate":"2020-07-01","checkoutDate":"2020-07-05","room":"Y,Y,Y"}
Consider I have following json:
{ "version": "1.0" }
I can parse it to dynamic JObject and use:
dynamic result = JObject.Parse(myJson);
string verison = result.Version; //works <3
But server returns the following json
{ { "version": "1.0" } }
This json is consider as valid by newtonsoft, but cannot access version anymore:
dynamic result = JObject.Parse(myJson);
string verison = result.Version; //error
How to access Version when onlt dynamic result is avalable?
{ { "version": "1.0" } } This json is consider as valid by newtonsoft
That is incorrect, you will not be able to parse this and will receive a exception of type Newtonsoft.Json.JsonReaderException (with: Invalid property identifier character: {. Path '', line 1, position 2.)
Invalid JSON:
{ { "version": "1.0" } }
Valid JSON:
{ "version": "1.0" }
(In case you have server control, I suggest you make the necessary steps on the server to return valid JSON)
However, worst case scenario, you could make this invalid JSON valid by removing the first char { and last char } before parsing it. For example like so:
var myJson = json.Substring(1, json.Length - 2);
dynamic result = JObject.Parse(myJson);
string version = result.version;
Where json here was the original response containing the invalid JSON.
Also note that for the JSON you provided you must use lowercase version as result.version. The dynamic property name must match exactly the one in the JSON
I think you trouble in capital "V" in "Version". Should be "result.version"
I have a json string that I will like to grab only the array in the data node. Do I trim using RegEx or what is the best way to extract that portion of the json string?
Here is a sample:
{
"Data":[
{
"Title":"Test Item 1",
"Icon":"pdf",
"PublicationDate":"2013-05-08T18:23:18.037Z"
},
{
"Title":"Test Item 2",
"Icon":"pdf",
"PublicationDate":"2013-05-08T18:23:38.177Z"
}
],
"Count":67
}
Below is what I want to end up with:
[
{
"Title":"Test Item 1",
"Icon":"pdf",
"PublicationDate":"2013-05-08T18:23:18.037Z"
},
{
"Title":"Test Item 2",
"Icon":"pdf",
"PublicationDate":"2013-05-08T18:23:38.177Z"
}
]
How can I do this properly? Sometimes the json string already comes as I need with only the array in the data node, so the logic has to be smart enough to ignore it if it already comes in that format. The reason is because I am feeding both cases to JsonConvert.DeserializeObject<List<dynamic>>(json). Thanks for any help!
After reading your comments, it seems that this is what you need:
var jToken=JToken.Parse(data);
JArray arr;
switch(jToken.Type)
{
case JTokenType.Array:
arr=(JArray)jToken;
break;
case JTokenType.Object:
arr=(JArray)((JObject)jToken)["Data"];
break;
default:
throw new Exception();
}
var output=arr.ToString();