首页 > 解决方案 > 如何在 C# 中获取 JSON 中的最后一项

问题描述

我正在尝试从 Azure Rest API 的 JSON 响应中获取单个值。

下面是我能够到达最终数组但无法从该数组中获取最后一项的代码。

            string token = await GetAccessToken(GMETenantID, GMEClientID, GMEAppKey);

            var httpClient = new HttpClient
            {
                BaseAddress = new Uri("https://management.azure.com/subscriptions/")
            };
            string URI = $"/subscriptions/{SubscriptionGUID}/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01";

            httpClient.DefaultRequestHeaders.Remove("Authorization");
            httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
            HttpResponseMessage response = await httpClient.GetAsync(URI).ConfigureAwait(false);

            var HttpsResponse = await response.Content.ReadAsStringAsync();
            dynamic Result = JsonConvert.DeserializeObject<object>(HttpsResponse);

            foreach (dynamic item in Result["value"])
            {
                string StorageID = item.id;
                string StorageAccountName = item.name;
                string ResourceType = item.type;

                int CharsToRemove = 12 + ResourceType.Length + StorageAccountName.Length;

                string ResourceGroupName = StorageID.Remove(0,67);
                ResourceGroupName = ResourceGroupName.Remove(ResourceGroupName.Length - CharsToRemove);

                string StartTime = DateTime.Now.AddDays(-7).ToString("yyyy-MM-ddTHH:mm:ss") + "Z"; ;
                string EndTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss") + "Z";

                var BlobhttpClient = new HttpClient
                {
                    BaseAddress = new Uri("https://management.azure.com/subscriptions/")
                };

                string BlobURI = $"/subscriptions/{SubscriptionGUID}/resourceGroups/{ResourceGroupName}/providers/{ResourceType}/{StorageAccountName}/blobServices/default/providers/microsoft.insights/metrics?timespan={StartTime}/{EndTime}&aggregation=average&metricnames=BlobCapacity&api-version=2018-01-01";
                BlobhttpClient.DefaultRequestHeaders.Remove("Authorization");
                BlobhttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
                HttpResponseMessage Blobresponse = await httpClient.GetAsync(BlobURI).ConfigureAwait(false);
                var BlobHttpsResponse = await Blobresponse.Content.ReadAsStringAsync();

                dynamic value = JObject.Parse(BlobHttpsResponse);

                foreach (dynamic List1 in value["value"])
                {
                    foreach (dynamic List2 in List1["timeseries"])
                    {
                        foreach (dynamic List3 in List2["data"])
                        {
                            Console.WriteLine((long?)List3["average"]);
                        }
                    }
                }
            }
            Console.ReadLine();

我还觉得必须有一种更简单的方法来获取这个值,而不是使用 3 个 Foreach 循环。

HttpsResponse:(实际响应中有 168 个时间戳和平均值,但我只输入了 3 个值)

{
  "cost": 0,
  "timespan": "2020-05-22T03:04:46Z/2020-05-29T03:04:46Z",
  "interval": "PT1H",
  "value": [
    {
      "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/MyResourceGroupName/providers/Microsoft.Storage/storageAccounts/MyAstorageAccountName/blobServices/default/providers/Microsoft.Insights/metrics/BlobCapacity",
      "type": "Microsoft.Insights/metrics",
      "name": {
        "value": "BlobCapacity",
        "localizedValue": "Blob Capacity"
      },
      "displayDescription": "The amount of storage used by the storage account's Blob service in bytes.",
      "unit": "Bytes",
      ".timeseries": [
        {
          "metadatavalues": [],
          "data": [
            {
              "timeStamp": "2020-05-22T03:04:00Z",
              "average": 586904516140.0
            },
            {
              "timeStamp": "2020-05-22T04:04:00Z",
              "average": 587058965680.0
            },
            {
              "timeStamp": "2020-05-22T05:04:00Z",
              "average": 587058965680.0
            }
          ]
        }
      ],
      "errorCode": "Success"
    }
  ],
  "namespace": "Microsoft.Storage/storageAccounts/blobServices",
  "resourceregion": "eastus2"
}

我想要的只是数字 587058965680,它是 JSON 的最后一个值和最近的时间戳。

几乎我想以我在 powershell 代码下面的方式获得确切的结果 PowerShell 的工作方式就像 4 行的魅力,但我不得不用 C# 写这么多行

$StorageAccounts = Get-AzStorageAccount -ResourceGroupName "My ResourceGroupName"

$StorageAccountID = $StorageAccounts.ID + "/blobServices/default"
$Start = (get-date).AddDays(-7)
$End = get-date

$Metric = Get-AzMetric -ResourceId $StorageAccountID -MetricName "BlobCapacity" -StartTime $Start -EndTime $End  -WarningAction Ignore

$ContainerSize = ($Metric.Data | sort-object -Descending Average | Select-Object -First 1).Average/1024/1024/1024

标签: c#restforeachazure-blob-storage

解决方案


为它创建一个简单的模型:

public class Data
{
    [JsonProperty("timeStamp")]
    public DateTime TimeStamp { get; set; }

    [JsonProperty("average")]
    public decimal Average { get; set; }
}

现在,只需使用JObject导航到datajson 中的键,并对其进行反序列化。

var jObj = JObject.Parse(json);
var data = jObj["value"][0][".timeseries"][0]["data"].ToString();
var dataList = JsonConvert.DeserializeObject<IEnumerable<Data>>(data);

然后,您可以使用 Linq 获取数组中的最后一个元素:

var last = dataList.Last();

如果您不想使用Models,您可以使用直接访问这些值JObject

所以,你可以直接这样做:

var jObj = JObject.Parse(json);
var data = jObj["value"][0][".timeseries"][0]["data"].Last();
var avg = data["average"];

推荐阅读