How to Linq a JSON

Can I LINQ a JSON?

No need for Linq, just use dynamic (using Json.Net)

dynamic obj = JObject.Parse(json);
Console.WriteLine((string)obj.picture.data.url);

Linq version would not be much readable

JObject jObj = JObject.Parse(json);
var url = (string)jObj.Descendants()
.OfType<JProperty>()
.Where(p => p.Name == "url")
.First()
.Value;

Documentation: LINQ to JSON

How to convert a JSON string using LINQ in C#

I think I have found where it has gone wrong.

"value":[...] 

is an array so you either access all the array items( in this case there is only one) or in your query specify the value item in this case would be ["value"][0]

I am not sure if value does need to be an array. Nevertheless this now works:

        var result = from s in gS["value"][0]["scheduleItems"]
orderby s["start"]["dateTime"]
select new
{
startTime = (DateTime)s["start"]["dateTime"],
endTime = (DateTime)s["end"]["dateTime"]
};

enter image description here

Query JSON Nested Object using LINQ

Once you have JObject parsed, you can get requested result like this:

var jObject = JObject.Parse(json);

var shapes = jObject["channel"]["region"]
.SelectMany(j => j["shape"]);

var confidences = shapes
.SelectMany(s => s.Select(i => i["confidence"]
.Value<float>()))
.ToList();

var result = new
{
ShapesCount = confidences.Count,
AverageConfidence = confidences.Average()
};

Query a JSON using LINQ

Demo on dotnet fiddle

You can use Newtonsoft to DeserializeObject then get values as you wish like below.

public class Program
{
public static void Main()
{
var json = "{\"fuel_distance\": 461.6, \"fuel_distance_um\": \"MI\", \"id\": \"62157\", \"stops\": [{ \"id\": \"zz1dnvtir8j050oW100204\", \"latitude\": 34.0214 }]}";
var deserializedObject = JsonConvert.DeserializeObject<MyModel>(json);
Console.WriteLine("Id: " + deserializedObject.id);

var stopIds = deserializedObject.stops.Select(p => p.id);
foreach(var id in stopIds)
Console.WriteLine("Id child: "+ id);
}
}

public class MyModel
{
public decimal fuel_distance {get; set;}
public string fuel_distance_um {get; set;}
public string id {get; set;}
public MyChildModel[] stops {get; set;}
}

public class MyChildModel
{
public string id {get; set;}
public decimal latitude {get; set;}
}

Output

Id: 62157
Id child: zz1dnvtir8j050oW100204

Updated

You can also get the result like below

    var result = new
{
ID = deserializedObject.id,
stopId = deserializedObject.stops[0].id
};

Send JSON via POST in C# and Use LINQ to access Objects

You go to http://quicktype.io (or similar online service, jsonutils, json2csharp, or use the Visual studio Paste Json as Classes feature - of all the sites that do this QT is the most full featured) to turn your json into classes. This makes it nicer to work with:

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using SomeNamespaceHere;
//
// var rootClassNameHere = RootClassNameHere.FromJson(jsonString);

namespace SomeNamespaceHere
{
using System;
using System.Collections.Generic;

using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public partial class RootClassNameHere
{
[JsonProperty("@odata.context")]
public Uri OdataContext { get; set; }

[JsonProperty("value")]
public Value[] Value { get; set; }
}

public partial class Value
{
[JsonProperty("emailAddress")]
public EmailAddress EmailAddress { get; set; }

[JsonProperty("automaticReplies")]
public AutomaticReplies AutomaticReplies { get; set; }
}

public partial class AutomaticReplies
{
[JsonProperty("message")]
public string Message { get; set; }

[JsonProperty("messageLanguage")]
public MessageLanguage MessageLanguage { get; set; }

[JsonProperty("scheduledStartTime")]
public ScheduledTime ScheduledStartTime { get; set; }

[JsonProperty("scheduledEndTime")]
public ScheduledTime ScheduledEndTime { get; set; }
}

public partial class MessageLanguage
{
[JsonProperty("locale")]
public string Locale { get; set; }

[JsonProperty("displayName")]
public string DisplayName { get; set; }
}

public partial class ScheduledTime
{
[JsonProperty("dateTime")]
public string DateTime { get; set; }

[JsonProperty("timeZone")]
public string TimeZone { get; set; }
}

public partial class EmailAddress
{
[JsonProperty("name")]
public string Name { get; set; }

[JsonProperty("address")]
public string Address { get; set; }
}

public partial class RootClassNameHere
{
public static RootClassNameHere FromJson(string json) => JsonConvert.DeserializeObject<RootClassNameHere>(json, SomeNamespaceHere.Converter.Settings);
}

public static class Serialize
{
public static string ToJson(this RootClassNameHere self) => JsonConvert.SerializeObject(self, SomeNamespaceHere.Converter.Settings);
}

internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}

(I chose "SomeNamespaceHere" and "RootClassNameHere" for the relevant names of namespace and class root; you might choose different)

And then you use it like this (the deser step will work differently depending on the service you used):

var rootClassNameHere = RootClassNameHere.FromJson(jsonString); //deser
var someLinq = rootClassNameHere.Value.Select(v => v.AutomaticReplies.Message); //query

C# LINQ Query to List of Nested JSON

Here's the simple solution you can try. First, map the JSON to Model(POCO) and deserialize the JSON apply LINQ and get an object with all your values.

Model classes for properties you want from JSON.

public partial class Values
{
[JsonProperty("value")] public List<Value> Value { get; set; }
}

public partial class Value
{
[JsonProperty("name")] public string Name { get; set; }

[JsonProperty("properties")] public ValueProperties Properties { get; set; }
}

public partial class ValueProperties
{
[JsonProperty("addressSpace")] public AddressSpace AddressSpace { get; set; }

[JsonProperty("virtualNetworkPeerings")]
public List<VirtualNetworkPeering> VirtualNetworkPeerings { get; set; }
}

public partial class AddressSpace
{
[JsonProperty("addressPrefixes")] public List<string> AddressPrefixes { get; set; }
}

public partial class VirtualNetworkPeering
{
[JsonProperty("properties")] public VirtualNetworkPeeringProperties Properties { get; set; }
}

public partial class VirtualNetworkPeeringProperties
{
[JsonProperty("remoteAddressSpace")] public AddressSpace RemoteAddressSpace { get; set; }
}

Deserialize the JSON and get desired properites:

var values = JsonConvert.DeserializeObject<Values>(json);
var desiredValues = values.Value
.Select(x => new
{
NetworkName = x.Name,
HostNetwork = x.Properties.AddressSpace.AddressPrefixes.Select(address => address).ToList(),
PeeredNets = x.Properties.VirtualNetworkPeerings
.SelectMany(peering => peering.Properties.RemoteAddressSpace.AddressPrefixes).Select(address => address).ToList()
}).ToList();

Note This requires you to install Newtonsoft.Json

C# linq to json how to read a property value within a Array

You can try this in your case:

var Land_use = jsondata["records"].Values("land_use_type").Single().ToString();

Land_use will be "3".

Or you can do:

var Land_use = var Land_use = jsondata["records"].Values("land_use_type").FirstOrDefault()?.Value<string>();


Related Topics



Leave a reply



Submit