繁体   English   中英

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.IList 问题

[英]Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IList problem

我想使用模型解析 Json 文件并将数据存储在列表中,当我尝试时,它给了我以下错误:

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.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 to c# Converter (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();
        }
    }
}

我尝试了不同的东西,但它不起作用,如果您有任何想法,感谢您分享它们,请保持温和,我是新手。

编辑

我正在使用的新主类(它帮助我更轻松地调试):

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);
            }
        }
    }
}

您需要阅读您的响应并反序列化字符串,如下所示。 对于您的场景,我使用的是Newtonsoft包,它是 .NET 的流行高性能 JSON 框架:

if (result.IsSuccessStatusCode)
{
  var readTask = result.Content.ReadAsAsync().Result;
  readTask.Wait();
  Console.WriteLine("\n ReadTask: " + readTask);
  //Get your de-serialized JSON here into your model
  var model = JsonConvert.DeserializeObject<PrometheusJson>(readTask).ToList();
}

发生错误是因为您的 json 文件仅对应于PrometheusJson对象而不是List<PrometheusJson> ,因此当我将代码修改为下面并且它可以工作时:

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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM