I have been attempting to create a LINQ query in C# which will allow me to create a List<> from different properties in the JSON string, which are of interest to me.
I have attempted a number of different approaches of.Select() and.SelectMany() but always end up with creating an exception. To unblock I have resorted to creating 2 or 3 independent Linq Queries which will extract the data I care about and then append these to a List.
Of course, this is utterly ugly; and therefore I am here asking from some guidance on how to do this correctly. I am not a professional developer, and IT Pro lost in DevOps; so please be kind!
This is a sample of the JSON payload
{
"value": [
{
"name": "p-we1net-network-vnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet",
"type": "Microsoft.Network/virtualNetworks",
"location": "westeurope",
"tags": {
"IaCVersion": "logsRetentionDays-20200505.02",
"ConfigVersion": "1.0.0.0"
},
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "e7619105-bd1c-4110-b19f-f465c5743899",
"addressSpace": {
"addressPrefixes": [
"99.111.0.0/22"
]
},
"dhcpOptions": {
"dnsServers": []
},
"subnets": [
{
"name": "GatewaySubnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet/subnets/GatewaySubnet",
"properties": {
"provisioningState": "Succeeded",
"addressPrefix": "99.111.0.0/24",
"routeTable": {
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/routeTables/p-we1net-network-vnet-GatewaySubnet-rt"
},
"ipConfigurations": [
{
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworkGateways/p-we1net-network-vpn/ipConfigurations/vnetGatewayConfig"
}
],
"serviceEndpoints": [
{
"provisioningState": "Succeeded",
"service": "Microsoft.Storage",
"locations": [
"westeurope",
"northeurope"
]
}
],
"delegations": [],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
},
"type": "Microsoft.Network/virtualNetworks/subnets"
},
{
"name": "AzureFirewallSubnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet/subnets/AzureFirewallSubnet",
"properties": {
"provisioningState": "Succeeded",
"addressPrefix": "99.111.1.0/24",
"routeTable": {
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/routeTables/p-we1net-network-vnet-AzureFirewallSubnet-rt"
},
"ipConfigurations": [
{
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/azureFirewalls/p-we1net-network-fw/azureFirewallIpConfigurations/p-we1net-network-fw-pip001"
}
],
"serviceEndpoints": [
{
"provisioningState": "Succeeded",
"service": "Microsoft.AzureActiveDirectory",
"locations": [
"*"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.AzureCosmosDB",
"locations": [
"*"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.CognitiveServices",
"locations": [
"*"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.ContainerRegistry",
"locations": [
"*"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.EventHub",
"locations": [
"*"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.KeyVault",
"locations": [
"*"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.ServiceBus",
"locations": [
"*"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.Sql",
"locations": [
"westeurope"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.Storage",
"locations": [
"westeurope",
"northeurope"
]
},
{
"provisioningState": "Succeeded",
"service": "Microsoft.Web",
"locations": [
"*"
]
}
],
"delegations": [],
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
},
"type": "Microsoft.Network/virtualNetworks/subnets"
}
],
"virtualNetworkPeerings": [
{
"name": "p-we1waf-network-vnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet/virtualNetworkPeerings/p-we1waf-network-vnet",
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "dee9953a-82b7-0f66-01ad-c11f82585928",
"peeringState": "Connected",
"remoteVirtualNetwork": {
"id": "/subscriptions/guid/resourceGroups/p-we1waf-network/providers/Microsoft.Network/virtualNetworks/p-we1waf-network-vnet"
},
"allowVirtualNetworkAccess": true,
"allowForwardedTraffic": false,
"allowGatewayTransit": true,
"useRemoteGateways": false,
"doNotVerifyRemoteGateways": false,
"remoteAddressSpace": {
"addressPrefixes": [
"99.111.4.0/22"
]
},
"routeServiceVips": {}
},
"type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings"
},
{
"name": "p-we1dc-network-vnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet/virtualNetworkPeerings/p-we1dc-network-vnet",
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "e3fad777-dac9-037a-1814-3609d6a3286c",
"peeringState": "Connected",
"remoteVirtualNetwork": {
"id": "/subscriptions/guid/resourceGroups/p-we1dc-network/providers/Microsoft.Network/virtualNetworks/p-we1dc-network-vnet"
},
"allowVirtualNetworkAccess": true,
"allowForwardedTraffic": false,
"allowGatewayTransit": true,
"useRemoteGateways": false,
"doNotVerifyRemoteGateways": false,
"remoteAddressSpace": {
"addressPrefixes": [
"99.111.8.0/25"
]
},
"routeServiceVips": {}
},
"type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings"
},
{
"name": "p-we1rmt-network-vnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet/virtualNetworkPeerings/p-we1rmt-network-vnet",
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "2e9593b3-d730-0251-1e39-87d3b767cc06",
"peeringState": "Connected",
"remoteVirtualNetwork": {
"id": "/subscriptions/guid/resourceGroups/p-we1rmt-network/providers/Microsoft.Network/virtualNetworks/p-we1rmt-network-vnet"
},
"allowVirtualNetworkAccess": true,
"allowForwardedTraffic": false,
"allowGatewayTransit": true,
"useRemoteGateways": false,
"doNotVerifyRemoteGateways": false,
"remoteAddressSpace": {
"addressPrefixes": [
"99.111.8.128/25"
]
},
"routeServiceVips": {}
},
"type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings"
},
{
"name": "t-tstsp1-network-vnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet/virtualNetworkPeerings/t-tstsp1-network-vnet",
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "4ed7d2c0-ecba-06ae-0cc5-90595382193c",
"peeringState": "Connected",
"remoteVirtualNetwork": {
"id": "/subscriptions/guid/resourceGroups/t-tstsp1-network/providers/Microsoft.Network/virtualNetworks/t-tstsp1-network-vnet"
},
"allowVirtualNetworkAccess": true,
"allowForwardedTraffic": false,
"allowGatewayTransit": true,
"useRemoteGateways": false,
"doNotVerifyRemoteGateways": false,
"remoteAddressSpace": {
"addressPrefixes": [
"99.111.9.0/25"
]
},
"routeServiceVips": {}
},
"type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings"
},
{
"name": "t-tstsp2-network-vnet",
"id": "/subscriptions/guid/resourceGroups/p-we1net-network/providers/Microsoft.Network/virtualNetworks/p-we1net-network-vnet/virtualNetworkPeerings/t-tstsp2-network-vnet",
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "8a4eb533-d883-0725-13a8-ebd4d3973fbe",
"peeringState": "Connected",
"remoteVirtualNetwork": {
"id": "/subscriptions/guid/resourceGroups/t-tstsp2-network/providers/Microsoft.Network/virtualNetworks/t-tstsp2-network-vnet"
},
"allowVirtualNetworkAccess": true,
"allowForwardedTraffic": false,
"allowGatewayTransit": true,
"useRemoteGateways": false,
"doNotVerifyRemoteGateways": false,
"remoteAddressSpace": {
"addressPrefixes": [
"99.111.9.128/25"
]
},
"routeServiceVips": {}
},
"type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings"
}
],
"enableDdosProtection": false,
"enableVmProtection": false
}
}
]
}
What I am looking to extract to a list is the following nodes, to an object/class
NetworkName (string)
["Value"][0][Name]
HostNetwork (List) ["Value"][0][properties][addressPrefixes]
PeeredNets (List) ["Value"][0][properties][virtualNetworkPeerings][x][properties][remoteAddressSpace][addressPrefixes]
Now, for the embarrassing part, this is the code I created; feel free to redact this: :)
try {
JObject root = JObject.Parse(response);
// Get the VNET Name
cidrData.name = root["value"][0]["name"].ToString();
Console.WriteLine($"Name: {cidrData}");
// Get the Supernets
JArray superNet = new JArray(root["value"][0]["properties"]["addressSpace"]["addressPrefixes"]);
cidrData.supernet = superNet.FirstOrDefault()[0].ToString();
foreach(var item in superNet){
Console.WriteLine($"SuperNets: {item[0].ToString()}");
}
// Get the Subnets
cidrData.subnets = new List<string>();
var networkPeeringList = JObject.Parse(response)
.Descendants()
.Where(x => x is JObject)
.Where(x => x["name"] != null )
.Select(x => new {
name = (string)x["name"],
data = (string)x["properties"].ToString()
})
.ToList();
foreach (var peeredNetwork in networkPeeringList)
{
Console.WriteLine($" {peeredNetwork.name}");
var netData = JObject.Parse(peeredNetwork.data)
.Descendants()
.Where(x => x is JObject)
.Where(x => x["addressPrefixes"] != null )
.Select(x => new {
name = x["addressPrefixes"]
})
.ToList();
foreach (var record in netData) {
var subnet = record.name[0].ToString();
cidrData.subnets.Add(subnet);
Console.WriteLine($" {subnet}");
}
}
}
Can anyone tell me how to do this more elegantly; preferably with a single LINQ query to cheery pick the values from the JSON?
Cheers
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.