Я хочу проанализировать файл Json с использованием модели и сохранить данные в списке, при попытке выдать следующую ошибку:
Невозможно десериализовать текущий объект JSON (например, {"name": "value"}) в тип 'System.Collections.Generi c .IList`1 [Prometheus_model.PrometheusJson]', поскольку для типа требуется массив JSON (например, [1,2,3 ]) для правильной десериализации.
Вот мой Json файл:
{
"status": "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {
"__name__": "wmi_logical_disk_free_bytes",
"instance": "192.168.1.71:9182",
"job": "prometheus",
"volume": "C:"
},
"value": [
1582530372.189,
"67817701376"
]
},
{
"metric": {
"__name__": "wmi_logical_disk_free_bytes",
"instance": "192.168.1.71:9182",
"job": "prometheus",
"volume": "D:"
},
"value": [
1582530372.189,
"13367246848"
]
},
{
"metric": {
"__name__": "wmi_logical_disk_free_bytes",
"instance": "192.168.1.71:9182",
"job": "prometheus",
"volume": "HarddiskVolume1"
},
"value": [
1582530372.189,
"68157440"
]
},
{
"metric": {
"__name__": "wmi_logical_disk_free_bytes",
"instance": "192.168.1.71:9182",
"job": "prometheus",
"volume": "HarddiskVolume3"
},
"value": [
1582530372.189,
"365953024"
]
}
]
}
}
моей модели (Prometheus_model), я сгенерировал ее с помощью конвертера Json в c# (QuickType):
using System;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Prometheus_model
{
public partial class PrometheusJson
{
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("data")]
public Data Data { get; set; }
}
public partial class Data
{
[JsonProperty("resultType")]
public string ResultType { get; set; }
[JsonProperty("result")]
public Result[] Result { get; set; }
}
public partial class Result
{
[JsonProperty("metric")]
public Metric Metric { get; set; }
[JsonProperty("value")]
public Value[] Value { get; set; }
}
public partial class Metric
{
[JsonProperty("__name__")]
public string Name { get; set; }
[JsonProperty("instance")]
public string Instance { get; set; }
[JsonProperty("job")]
public string Job { get; set; }
[JsonProperty("volume")]
public string Volume { get; set; }
}
public partial struct Value
{
public double? Double;
public string String;
public static implicit operator Value(double Double) => new Value { Double = Double };
public static implicit operator Value(string String) => new Value { String = String };
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ValueConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ValueConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(Value) || t == typeof(Value?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Integer:
case JsonToken.Float:
var doubleValue = serializer.Deserialize<double>(reader);
return new Value { Double = doubleValue };
case JsonToken.String:
case JsonToken.Date:
var stringValue = serializer.Deserialize<string>(reader);
return new Value { String = stringValue };
}
throw new Exception("Cannot unmarshal type Value");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (Value)untypedValue;
if (value.Double != null)
{
serializer.Serialize(writer, value.Double.Value);
return;
}
if (value.String != null)
{
serializer.Serialize(writer, value.String);
return;
}
throw new Exception("Cannot marshal type Value");
}
public static readonly ValueConverter Singleton = new ValueConverter();
}
}
Мой основной класс:
using Newtonsoft.Json;
using Prometheus_model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
namespace Test_api.v2
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
IEnumerable<PrometheusJson> dataG = null;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:9090/api/v1/");
//HTTP GET
var responseTask = client.GetAsync("query?query=wmi_logical_disk_free_bytes");
responseTask.Wait();
Console.WriteLine("\n responseTask: " + responseTask);
var result = responseTask.Result;
Console.WriteLine("\n result: "+result);
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<PrometheusJson>>();
readTask.Wait();
Console.WriteLine("\n ReadTask: " + readTask);
dataG = readTask.Result;
Console.WriteLine("\n DataG: "+dataG);
}
else //web api sent error response
{
//log response status here..
Console.WriteLine("error");
}
}
Console.WriteLine("\n\n\n End");
Console.ReadLine();
}
}
}
Я пробовал разные вещи, но это не работает, если у вас есть идеи, спасибо, что поделились ими, и будьте добры, пожалуйста, я новичок ie.
РЕДАКТИРОВАТЬ
Новый основной класс, который я использую (это помогает мне отлаживать проще):
using Newtonsoft.Json;
using Prometheus_model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
namespace Test_api.v2
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
List<PrometheusJson> dataG = new List<PrometheusJson>();
using (var httpClient = new HttpClient())
{
using (var response = await httpClient
.GetAsync("http://localhost:9090/api/v1/query?query=wmi_logical_disk_free_bytes"))
{
string apiResponse = await response.Content.ReadAsStringAsync();
dataG = JsonConvert.DeserializeObject<List<PrometheusJson>>(apiResponse).ToList();
}
Console.WriteLine(dataG);
}
}
}
}
РЕДАКТИРОВАТЬ: это сработало, спасибо @XingZou, вот основной класс:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
namespace Test_api.v2
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
List<PrometheusJson> dataG = new List<PrometheusJson>();
using (var httpClient = new HttpClient())
{
using (var response = await httpClient
.GetAsync("http://localhost:9090/api/v1/query?query=wmi_logical_disk_free_bytes"))
{
string apiResponse = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<PrometheusJson>(apiResponse);
dataG.Add(data);
}
Console.WriteLine(dataG);
}
}
}
}