【问题标题】:How to fetch the last item in a JSON in C#如何在 C# 中获取 JSON 中的最后一项
【发布时间】:2020-09-17 16:05:00
【问题描述】:

我正在尝试从 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# rest foreach azure-blob-storage


    【解决方案1】:

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

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

    现在,只需使用 JObject 导航到 json 中的 data 键,然后对其进行反序列化。

    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"];
    

    【讨论】:

      【解决方案2】:

      使用Newtonsoft.Json.Linq 可能对这种特殊情况有所帮助。

      例如:

      
      IList<long> averages = 
          value["value"].SelectMany(val => val[".timeseries"]
                        .SelectMany(tm => tm["data"]
                        .Select(ave => (long) ave["average"]))).ToList();
      
      

      输出:

      [0] 586904516140
      [1] 587058965680
      [2] 587058965680
      

      【讨论】:

        【解决方案3】:

        我用一种奇怪的逻辑以某种方式解决了它:)

        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);
                        long FinalValue = 0;
                        foreach (dynamic List1 in value["value"])
                        {
                            foreach (dynamic List2 in List1["timeseries"])
                            {
                                foreach (dynamic List3 in List2["data"])
                                {                            
                                    if (List3["average"] != null)
                                    {
                                        long NewData = List3["average"];
                                        
                                        if (NewData > FinalValue)
                                        {
                                            FinalValue = NewData;
                                        }
                                        else if (NewData > FinalValue)
                                        {
                                            FinalValue = NewData;
                                        }
        
                                    }
                                }
                            }
                        }
                        Console.WriteLine(""); 
                        Console.WriteLine(FinalValue);
                        Console.WriteLine($"Done with StorageAccount: {StorageAccountName}");                
                    }
                    Console.ReadLine();

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-15
          • 2020-09-27
          • 2014-02-18
          • 2010-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多