I have a json object as follows:
"dnsNames": {
"type": "array",
"defaultValue": [
"something.else.com",
"something.com",
"else.com"
]
}
I'd like to read that into a List<string> the same way I can read it into a string (i.e. without creating a class for it):
JObject jsonParameters = JObject.Parse(File.ReadAllText(filePath));
string test = jsonParameters["parameters"]["dnsNames"]["defaultValue"].ToString();
Just unsure if that's possible or what the syntax for it might be.
Navigate the object structure as you see it dnsNames.defaultValue then convert that object to a given type (List<string> in our case):
var json =
#"{""dnsNames"": {
""type"": ""array"",
""defaultValue"": [
""something.else.com"",
""something.com"",
""else.com""
]
}}";
var jObject = JObject.Parse(json);
var list = jObject["dnsNames"]["defaultValue"].ToObject<List<string>>();
// ?list
// Count = 3
// [0]: "something.else.com"
// [1]: "something.com"
// [2]: "else.com"
Related
I have a JSON string like below:
{
"MetaData": {
"ResourcesUsed": 1
},
"Result": [
{
"locations": [
{
"country": "Papua New Guinea",
"city": "Jacquinot Bay",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-08T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
},{
"country": "Papua New Guinea2",
"city": "Jacquinot Bay2",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-02T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
}
]
}
]
}
I converted it to a JSON object using Newtonsoft. What I want to do is to sort the locations array(s) inside the Result array by the utcDate field nested in each locations item. I found the following thread: C# Sort JSON string keys. However, I could not still implement it since I have arrays inside my object, while that question deals purely with sorting objects inside objects alphabetically by property name.
Here is a piece of code that I wrote so far:
public string GenerateJson()
{
var model = (JObject)JsonConvert.DeserializeObject(data);
Sort(model);
}
private void Sort(JObject jObj)
{
var props = jObj["Result"][0]["locations"].ToList();
foreach (var prop in props)
{
prop.Remove();
}
foreach (var prop in props.OrderBy(p => p.Name))
{
jObj.Add(prop);
if (prop.Value is JObject)
Sort((JObject)prop.Value);
if (prop.Value is JArray)
{
Int32 iCount = prop.Value.Count();
for (Int32 iIterator = 0; iIterator < iCount; iIterator++)
if (prop.Value[iIterator] is JObject)
Sort((JObject)prop.Value[iIterator]);
}
}
}
You can sort each individual "Result[*].locations" array using LINQ as follows:
// Load the JSON without parsing or converting any dates.
var model = JsonConvert.DeserializeObject<JObject>(data, new JsonSerializerSettings{ DateParseHandling = DateParseHandling.None });
// Construct a serializer that converts all DateTime values to UTC
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings{ DateTimeZoneHandling = DateTimeZoneHandling.Utc });
foreach (var locations in model.SelectTokens("Result[*].locations").OfType<JArray>())
{
// Then sort the locations by utcDate converting the value to UTC at this time.
var query = from location in locations
let utcDate = location.SelectToken("locTypeAttributes.utcDate").ToObject<DateTime>(serializer)
orderby utcDate
select location;
locations.ReplaceAll(query.ToList());
}
Notes:
The JSON is initially loaded using DateParseHandling.None to prevent the "localDate" and "utcDate" strings from being prematurely interpreted as DateTime objects with a uniform DateTime.Kind.
(For a discussion of how Json.NET interprets strings that look like dates, see Serializing Dates in JSON.)
We then iterate through all "locations" arrays using SelectTokens("Result[*].locations") where [*] is the JSONPath wildcard character, selecting all entries in the "Results" array.
We then order each "locations" array by deserializing the nested locTypeAttributes.utcDate to a UTC date, then ordering using LINQ.
Finally the array is updated using JArray.ReplaceAll().
If any locTypeAttributes.utcDate property is missing, an exception will be thrown. You could instead deserialize to DateTime? if that is a possibility.
Working sample .Net fiddle here.
I have the following Json , which has a dynamic set of values
[ {
"Type": "Animal" }, {
"Profession": "Dog" } ]
I want to read it into an object
List<List<KeyValuePair<String,String>>>
this works :
var objectList = JsonConvert.DeserializeObject<List<dynamic>>(rawStringJsonData);
but when I try
var objectList = JsonConvert.DeserializeObject<List<List<KeyValuePair<String,String>>>(rawStringJsonData);
I get an error
Additional information: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type
You can read it as a List<Dictionary<string,string>> and then cast it to
List<List<KeyValuePair<String,String>>>
Try this:
var rawStringJsonData = "[ { \"Type\": \"Animal\" }, { \"Profession\": \"Dog\" } ]";
var dictList = JsonConvert.DeserializeObject<List<Dictionary<string,string>>>(rawStringJsonData);
List<List<KeyValuePair<string,string>>> objectList =
dictList.Select(i => i.ToList()).ToList();
If you use the debugger to inspect the type of your first try, its just deserializing to a list of JTokens, and seeing as that you want a list of key value pairs I'd say that not really anything useful.
The List<List<KeyValuePair<String,String>>> datatype does not match your data. That would maybe look something like this
[ {"Key": "Type", "Value": "Animal" }, {"Key": "Profession", "Value": "Dog" } ]
In this case I'd probably deserialize to a dictionary instead:
var objectList = JsonConvert.DeserializeObject<List<Dictionary<string,string>>>(rawStringJsonData);
I have the following json which is in geojson format, and Id like to be able to parse this into a nested list in c#:
public IList<IList<IList<double>>> Coordinates { get; set; }
"coordinates": [
[
[-3.213338431720785, 55.940382588499197],
[-3.213340490487523, 55.940381867350276],
[-3.213340490487523, 55.940381867350276],
[-3.213814166228732, 55.940215021175085],
[-3.21413960035129, 55.940100842843712]
]
]
I have tried the following but I get an exception:
var node = jsonProperties["geometry"]["coordinates"].Values();
var coordinates = node.Select(x=>x.Value<List<double>>());
Exception detail:
Cannot cast Newtonsoft.Json.Linq.JArray to
Newtonsoft.Json.Linq.JToken.
To deserialize using newtonsoft. Create Foo class with a coordinates property, inclose the JSON script with curly brackets to denote it as an object then call JsonConvert.DeserializeObject<Foo>(Json).
private class Foo
{
public List<List<List<double>>> coordinates { get; set; }
}
var json = #"{
coordinates: [
[
[-3.213338431720785, 55.940382588499197],
[-3.213340490487523, 55.940381867350276],
[-3.213340490487523, 55.940381867350276],
[-3.213814166228732, 55.940215021175085],
[-3.21413960035129, 55.940100842843712]
]
]
}";
var result = JsonConvert.DeserializeObject<Foo>(json);
May not be exactly what you want but using dynamic type I could access the values. For example this sample code
class Program
{
static void Main(string[] args)
{
string sampleJson = #"{ ""coordinates"": [
[
[-3.213338431720785, 55.940382588499197],
[-3.213340490487523, 55.940381867350276],
[-3.213340490487523, 55.940381867350276],
[-3.213814166228732, 55.940215021175085],
[-3.21413960035129, 55.940100842843712]
]
]}";
dynamic d = JObject.Parse(sampleJson);
Console.WriteLine(d.coordinates[0].Count);
foreach (var coord in d.coordinates[0])
{
Console.WriteLine("{0}, {1}", coord[0], coord[1]);
}
Console.ReadLine();
}
displays the following:
5
-3.21333843172079, 55.9403825884992
-3.21334049048752, 55.9403818673503
-3.21334049048752, 55.9403818673503
-3.21381416622873, 55.9402150211751
-3.21413960035129, 55.9401008428437
I suggest you to parse them into something more suitable like List<Tuple<double, double>> though there is also solution for nested lists. Please check my inline comments:
const string json = #"
{
""coordinates"":
[
[
[-3.213338431720785, 55.940382588499197],
[-3.213340490487523, 55.940381867350276],
[-3.213340490487523, 55.940381867350276],
[-3.213814166228732, 55.940215021175085],
[-3.21413960035129, 55.940100842843712]
]
]
}";
var jsObject = JObject.Parse(json);
/*
* 1. Read property "coordinates" of your root object
* 2. Take first element of array under "coordinates"
* 3. Select each pair-array and parse their values as doubles
* 4. Make a list of it
*/
var result = jsObject["coordinates"]
.First()
.Select(pair => new Tuple<double, double> (
pair[0].Value<double>(),
pair[1].Value<double>()
)
).ToList();
And for List<List<List<double>>> please see #YTAM answer.
I have a JSON object that looks like this
{
"totalCount": 2,
"students": [{
"name": "abc",
"data": {
"Maths": 20,
"Science": 25
},
"score": 10.0
},
{
"name": "xyz",
"data": {
"Maths": 44,
"Science": 12
},
"score": 11.0
}]
}
I want to deserialize this JSON object to an IEnumerable<String> that contains all the names.
I want -
private IEnumerable<String> GetAllNames(string json) to return ["abc","xyz"]
This is just sample data (and not homework!!). Any advice on how to achieve this would be appreciated. I'm using Newtonsoft library but haven't been able to do this effectively yet. I do not want to iterate through the objects and construct the list myself, any direct way of doing this?
EDIT -
This is what I'm doing currently
var studentList = new List<string>();
var json = JsonConvert.DeserializeObject<dynamic>(jsonString);
foreach (var data in json.students)
{
catalogsList.Add(data.name.toString());
}
return catalogsList;
Try this:
private IEnumerable<string> GetAllNames(string json)
{
JObject jo = JObject.Parse(json);
return jo["students"].Select(s => s["name"].ToString());
}
I have a .js script that contain an array:
The output of the js is like:
var foo=
[
{
"bar1":"value1",
"bar2":"value2"
// And so on...
}
]
I have no access to the js source, so i cannot output as JSON and Deserialize.
I can only get this as a String using WebClient, but how i can parse it and create an Array/Dictionary and work on it inside C#?
You should consider calling WebClient.DownloadString . Then Parse using JSON.Net or whatever
As per the example provided over there
string json = #"{
""Name"": ""Apple"",
""Expiry"": "2008-12-28T00:00:00",
""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
var foo = new JavaScriptSerializer().Deserialize<List<YourModelHere>>(YourString);
You can use a JavaScriptSerializer to deserialize that string:
string str=
#"var foo =
[
{
""bar1"":""value1"",
""bar2"":""value2""
}
]";
JavaScriptSerializer js = new JavaScriptSerializer();
var o = js.Deserialize<Dictionary<string,string>[]>(str.Substring(str.IndexOf('[')));
Result:
Dictionary<String,String> (2 items)
Key Value
------ --------
bar1 value1
bar2 value2