Member 14202729 Ответов: 2

Ошибка десериализации данных json в ienumerable


Привет ребята,

Исключение, которое я получаю, заключается в следующем:

"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.IEnumerable`1 because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath 'result', line 2, position 12.


я понял, что мой json возвращает одиночные данные, и я пытаюсь десериализовать интерфейс IEnumerable, чтобы я мог циклически просматривать его список.

Мои данные json:

{
"result":[
{"Alert Message":" unreachable[Down]",
"Event Time":"2019-04-01 18:47:18",
"Threshold Value":"Down",
"Source Type":"ROUTER",
"Severity":"Unreachable",
"Metric Name":"Status",
"Source Host":"1.1.1.1"
}],
"success":"true",
"message":""
}


Что я уже пробовал:

Мой класс json:

class JsonData
    {
        [JsonProperty("Alert Message")]
        public string AlertMessage { get; set; }

        [JsonProperty("Event Time")]
        public DateTime EventTime { get; set; }


        [JsonProperty("Threshold Value")]
        public string ThresholdValue { get; set; }

        [JsonProperty("Source Type")]
        public string SourceType { get; set; }

        [JsonProperty("Severity")]
        public string Severity { get; set; }

        [JsonProperty("Metric Name")]
        public string MetricName { get; set; }

        [JsonProperty("Source Host")]
        public string SourceHost { get; set; }
    }



Мой код для десериализации:

using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

class ApiDemo
    {

string filepath = @"c:\jsonData.json";
            
                using (StreamReader r = new StreamReader(filepath))
                {
                    var json = r.ReadToEnd();
                    var jobj = JObject.Parse(json);
                    string  res = jobj.ToString();
IEnumerable<result> deserializedlistobj = (IEnumerable<result>)JsonConvert.DeserializeObject(res, typeof(IEnumerable<result>));


Я не могу понять, как перебирать коллекцию с помощью Ienumerator. Любая помощь или идея будут оценены по достоинству.

Richard MacCutchan

Как говорится в сообщении, данные, которые вы пытаетесь десериализовать, не являются распознанным массивом. Кроме того, где находится определение типа "результат".

2 Ответов

Рейтинг:
2

Jihed Haj Ali

Вы можете использовать такие сайты, как помощь в наборе для создания кода из данных JSON.

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using QuickType;
//
//    var welcome = Welcome.FromJson(jsonString);

namespace QuickType
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class Welcome
    {
        [JsonProperty("result")]
        public Result[] Result { get; set; }

        [JsonProperty("success")]
        [JsonConverter(typeof(ParseStringConverter))]
        public bool Success { get; set; }

        [JsonProperty("message")]
        public string Message { get; set; }
    }

    public partial class Result
    {
        [JsonProperty("Alert Message")]
        public string AlertMessage { get; set; }

        [JsonProperty("Event Time")]
        public DateTimeOffset EventTime { get; set; }

        [JsonProperty("Threshold Value")]
        public string ThresholdValue { get; set; }

        [JsonProperty("Source Type")]
        public string SourceType { get; set; }

        [JsonProperty("Severity")]
        public string Severity { get; set; }

        [JsonProperty("Metric Name")]
        public string MetricName { get; set; }

        [JsonProperty("Source Host")]
        public string SourceHost { get; set; }
    }

    public partial class Welcome
    {
        public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }

    internal class ParseStringConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(bool) || t == typeof(bool?);

        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
            var value = serializer.Deserialize<string>(reader);
            bool b;
            if (Boolean.TryParse(value, out b))
            {
                return b;
            }
            throw new Exception("Cannot unmarshal type bool");
        }

        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (bool)untypedValue;
            var boolString = value ? "true" : "false";
            serializer.Serialize(writer, boolString);
            return;
        }

        public static readonly ParseStringConverter Singleton = new ParseStringConverter();
    }
}


Рейтинг:
0

F-ES Sitecore

Ваши данные имеют свойство под названием "результат", которое представляет собой массив, поэтому вам нужен класс, который отражает это. Что-то вроде

class MyData
    {
        [JsonProperty("result")]
        public List<JsonData> Result { get; set; }

        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("message")]
        public string Message { get; set; }
}


затем десериализуйтесь до этого

MyData deserializedlistobj = (MyData)JsonConvert.DeserializeObject(res, typeof(MyData));


Member 14202729

Спасибо @Фес-технологического оборудования. Я могу десериализовать json в пользовательскую коллекцию классов под названием jsonData.Но я не уверен, как я получу указанные данные, такие как "EventTime" из данных json. как использовать запрос linq для получения указанного поля из данных json?

F-ES Sitecore

Что-то вроде

List<DateTime> eventTimes = deserializedlistobj.Result.Выберите(r => r.EventTime).Список();