gpt4 book ai didi

c# - 无法使用 C# 函数从 Json 文件中读取多个值

转载 作者:行者123 更新时间:2023-12-04 10:26:32 24 4
gpt4 key购买 nike

我正在尝试执行一个函数,该函数返回我在 Json 文件中获得的值的总和。
所以为此我创建了一个模型来反序列化 Json 文件,它是这样的:
使用 System.Collections.Generic;

namespace ServerMonitoringApi.Controllers.CpuUsage.Model
{
public class Metric
{
public string __name__ { get; set; }
public string core { get; set; }
public string instance { get; set; }
public string job { get; set; }
}

public class Result
{
public Metric metric { get; set; }
public IList<object> value { get; set; }
}

public class Data
{
public string resultType { get; set; }
public IList<Result> result { get; set; }
}

public class CpuUsageResponse
{
public string status { get; set; }
public Data data { get; set; }
}
}

它适用于反序列化等。我已经测试过了。

在我的 Controller 中,我有这个函数返回总和并导致问题:
[HttpGet("Number/{instance}&{port}")]
public async Task<double> GetNumCpuUsagePerInstance(string instance, string port)
{
string perInstanceLink = MetricApiLink + "{instance=\"" + instance + ":" + port + "\"}";
string idleModeLink = MetricApiLink +
"{mode=\"idle\",instance=\"" + instance + ":" + port + "\"}";
dynamic dataGetAll;
dynamic dataGetIdle;
using (var httpClient = new HttpClient())
{
using (var response = await httpClient
.GetAsync(perInstanceLink))
{
string apiResponse = await response.Content.ReadAsStringAsync();
dataGetAll = JsonConvert.DeserializeObject<CpuUsageResponse>(apiResponse);
}
}
using (var httpClient = new HttpClient())
{
using (var response = await httpClient
.GetAsync(idleModeLink))
{
string apiResponse = await response.Content.ReadAsStringAsync();
dataGetIdle = JsonConvert.DeserializeObject<CpuUsageResponse>(apiResponse);
}
}

double sum1 = 0;
double sum2 = 0;
NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberGroupSeparator = ".";

foreach(CpuUsageResponse x in dataGetAll)
{
sum1 += Convert.ToDouble(x.data.result[1].value[1], provider);
}

return sum1;
}

我已经测试了它们工作正常的每个功能,但是当我尝试执行“Foreach”时它不起作用并给我这个错误消息:

RuntimeBinderException: Cannot implicitly convert type 'ServerMonitoringApi.Controllers.CpuUsage.Model.CpuUsageResponse' to 'System.Collections.IEnumerable'. An explicit conversion exists (are you missing a cast?) And say that the error is in the line 123 which is:


    NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberGroupSeparator = ".";

/*here(line 123)->*/ foreach(CpuUsageResponse x in dataGetAll)
{
sum1 += Convert.ToDouble(dataGetAll.data.result[1].value[1], provider);
}

我的 Json 文件是这样的:
{
"status": "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,0",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"95595.25"
]
},
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,1",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"103647.703125"
]
},
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,2",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"94185.015625"
]
},
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,3",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"102109.203125"
]
},
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,4",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"96709.59375"
]
},
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,5",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"102046.5625"
]
},
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,6",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"98963.453125"
]
},
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,7",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583873150.877,
"89011.53125"
]
}
]
}
}

我正在尝试对索引为 1 的值求和,即 value[1]并归还

最佳答案

您的 JSON 由包含 data.result [] 的单个根对象组成。大批:

{
"status":"success",
"data":{
"resultType":"vector",
"result":[/* Results */]
}
}

每个结果如下所示:
{
"metric": {
"__name__": "wmi_cpu_time_total",
"core": "0,0",
"instance": "192.168.1.101:9182",
"job": "Server-monitoring-Api"
},
"value": [
1583851813.666,
"79186.65625"
]
}

因此,像您在此处尝试执行的操作一样,遍历最外层的 JSON 容器
foreach(CpuUsageResponse x in dataGetAll)
{
sum1 += Convert.ToDouble(x.data.result[1].value[1], provider);
}

真没意思。如果最外面的 JSON 容器是数组,那将是一件明智的事情。

相反,如果你想把所有 data.result[*].value[1] 加起来值转换为 double 结果,您可以按如下方式进行:
CpuUsageResponse dataGetAll;

// Download the apiResponse JSON string (code omitted)

dataGetAll = JsonConvert.DeserializeObject<CpuUsageResponse>(apiResponse);

var sum = dataGetAll.data.result
.Select(r => r.value[1])
.Select(s => Convert.ToDouble(s, NumberFormatInfo.InvariantInfo))
.Sum();

演示 fiddle here .

笔记:
  • 不是 声明 dataGetAlldynamic .通过这样做,您可以消除对代码正确性的所有编译时检查,并将其替换为运行时错误,例如 RuntimeBinderException您的问题中显示的异常。既然你创建了一个 c# 数据模型,你应该使用它,如果你有,你会收到一个更清晰的编译错误:
    CpuUsageResponse dataGetAll;

    dataGetAll = JsonConvert.DeserializeObject<CpuUsageResponse>(apiResponse);

    double sum1 = 0;
    NumberFormatInfo provider = new NumberFormatInfo();
    provider.NumberGroupSeparator = ".";

    //Compilation error (line 63, col 43): foreach statement cannot operate on variables of type 'CpuUsageResponse' because 'CpuUsageResponse' does not contain a public instance definition for 'GetEnumerator'
    foreach(CpuUsageResponse x in dataGetAll)
    {
    sum1 += Convert.ToDouble(x.data.result[1].value[1], provider);
    }

    演示 fiddle #2 here .

    When should one use dynamic keyword in c# 4.0? , Is the use of dynamic considered a bad practice?What is the 'dynamic' type in C# 4.0 used for?有关何时使用和不使用的进一步讨论,dynamic .
  • 您的 CpuUsageResponse对于提供的 JSON,数据模型看起来是正确的。
  • 而不是构建您自己的自定义 NumberFormatInfo ,您可以使用 NumberFormatInfo.InvariantInfo .
  • 关于c# - 无法使用 C# 函数从 Json 文件中读取多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60620156/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com