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