locked
JsonSerializationException RRS feed

  • Вопрос

  • Всем привет!

    Столкнулся с такой проблемой, при запуске приложения на устройстве выдает такую ошибку: 

    Исключение типа "Newtonsoft.Json.JsonSerializationException" возникло в Newtonsoft.Json.DLL, но не было обработано в коде пользователя

    Дополнительные сведения: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Double' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly.

    To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) 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.

    Path 'list[0].temp.day', line 1, position 191.

    в строке:

    RootObject result = JsonConvert.DeserializeObject<RootObject>(e.Result);

    и есть вот такой класс:

    public class Day
        {
            private int _dt;
    
            public int dt
            {
                get { return _dt; }
                set {
                    _dt = value;
                    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                    Time = epoch.AddSeconds(value);
                }
            }
    
            private DateTime _time;
            public DateTime Time
            {
                get { return _time; }
                set { _time = value; }
            }
    
            public double temp { get; set; }
            public double night { get; set; }
            public double eve { get; set; }
            public double morn { get; set; }
            public double pressure { get; set; }
            public int humidity { get; set; }
            public List<Weather> weather { get; set; }
            public double speed { get; set; }
            public double deg { get; set; }
    
            public string IconPath
            {
                get
                {
                    return "/Icons/" + weather[0].icon.Replace("d", "").Replace("n", "") + ".png";
                }
    
                set { }
            }
        }

    делаю вот по этому тутору: http://www.youtube.com/watch?v=zm2tOtr8ReM

    Заранее спасибо за ответ

    23 ноября 2014 г. 16:17

Ответы

  • да, конечно, иначе он просто не поймет его. Вы указали что на месте этого поля будет число, а на самом деле там объект
    28 ноября 2014 г. 20:34
  • А можете объяснить, почему мы делаем десереализацию RootObject?

    Да.

    Открываете JSON. Копируете его сюда(json2sharp). Получаем модельки. 

    Смотрим, у нас появился RootObject, а все остальные имеют нормальные названия. Почему? Потому что у него и нет названия. Json начинается с пары фигурных скобок. Это и есть RootObject.

    Так же для удобства я смотрю JSON через Json Editor Online

    Никто не заставляет называть его RootObject. Переименуйте как Вам хочется.

    Теперь насчет именование свойств - они здесь все с маленькой буквы. Можно сделать маппинг для удобства, что бы не привязываться к тем именам, которые в JSON.

    [JsonProperty(PropertyName = "speed")]
    public double Speed { get; set; }


    • Предложено в качестве ответа Mykyta Bondarenko 12 декабря 2014 г. 21:13
    • Помечено в качестве ответа Dmitrii Shimanov 16 декабря 2014 г. 16:53
    12 декабря 2014 г. 9:51

Все ответы

  • Так как вы используйте Newtonsoft.Json.DLL, так что задавать вопрос следует в форумах по данному продукту.

    Когда будетете спрашивать там то непременно следует запостить JSON который вызывает проблему и описать откуда вы его взяли.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    23 ноября 2014 г. 18:06
  • Покажите json.
    24 ноября 2014 г. 7:50
  • вот в чистом виде то вот по этой ссылке: http://api.openweathermap.org/data/2.5/forecast/daily?id=524901&units=metric

    24 ноября 2014 г. 13:45
  • Еще модель покажите для этого json, в которую Вы десериализуете.
    24 ноября 2014 г. 14:12
  • Это не проблема нугета, это проблема Вашей модели. В каком-то месте у Вас неправильный тип указан для парсинга.
    Поддерживаю Олега, покажите пожалуйста свою модель.
    24 ноября 2014 г. 19:06
  • тоже так думаю, но не вижу где ошибся. 

    public class City
        {
            public int id { get; set; }
            public string name { get; set; }
            public Coord coord { get; set; }
            public string country { get; set; }
            public int population { get; set; }
        }
    
        public class Weather
        {
            public int id { get; set; }
            public string main { get; set; }
            public string description { get; set; }
            public string icon { get; set; }
        }
    
        public class Day
        {
            private int _dt;
    
            public int dt
            {
                get { return _dt; }
                set {
                    _dt = value;
                    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                    Time = epoch.AddSeconds(value);
                }
            }
    
            private DateTime _time;
            public DateTime Time
            {
                get { return _time; }
                set { _time = value; }
            }
    
            public double temp { get; set; }
            public double night { get; set; }
            public double eve { get; set; }
            public double morn { get; set; }
            public double pressure { get; set; }
            public int humidity { get; set; }
            public List<Weather> weather { get; set; }
            public double speed { get; set; }
            public double deg { get; set; }
    
            public string IconPath
            {
                get
                {
                    return "/Icons/" + weather[0].icon.Replace("d", "").Replace("n", "") + ".png";
                }
    
                set { }
            }
        }
    
        public class RootObject
        {
            public string cod { get; set; }
            public string message { get; set; }
            public City city { get; set; }
            public int cnt { get; set; }
            public string model { get; set; }
            public List<Day> list { get; set; }
        }

    25 ноября 2014 г. 7:49
  • Объект 

     public double temp { get; set; }

    судя по предоставленному json'у, совсем не такого типа должен быть. А просто классом с определенным набором полей.


    26 ноября 2014 г. 21:55
  • Т.е. 
    public double temp { get; set; }
    вынести в отдельный класс и в него включить day, min, max и т.д.? 
    27 ноября 2014 г. 5:08
  • да, конечно, иначе он просто не поймет его. Вы указали что на месте этого поля будет число, а на самом деле там объект
    28 ноября 2014 г. 20:34
  • Я вынес Temp в отдельный класс, он получился вот такой: 

    public class Temp
        {
            public double day { get; set; }
            public double min { get; set; }
            public double max { get; set; }
            public double night { get; set; }
            public double eve { get; set; }
            public double morn { get; set; }
        }

    И в классе Day вписал вот так:

    public class Day
    {
    public Temp temp { get; set; }
    }
    DayList = new ObservableCollection<Day>();
                    DayList.Add(new Day { temp = 20, Time = DateTime.Now });

    И теперь у меня ошибка: Неявное преобразование типа int в App1.Model.Temp невозможно.

    Я понимаю, что нельзя присвоить целочисленное значение значение к полю temp, и собственно вопрос, как мне поступить в этом случае?

    7 декабря 2014 г. 13:58
  • using System;
    using System.Collections.Generic;
    using System.Net.Http;
    using Newtonsoft.Json;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                var program = new Program();
                program.Go();
                Console.ReadLine();
            }
    
    
            public async void Go()
            {
                var client = new HttpClient();
    
                var json = await client.GetStringAsync("http://api.openweathermap.org/data/2.5/forecast/daily?id=524901&units=metric");
                var result = JsonConvert.DeserializeObject<RootObject>(json);
            }
        }
    
        public class Coord
        {
            public double lon { get; set; }
            public double lat { get; set; }
        }
    
        public class City
        {
            public int id { get; set; }
            public string name { get; set; }
            public Coord coord { get; set; }
            public string country { get; set; }
            public int population { get; set; }
        }
    
        public class Temp
        {
            public double day { get; set; }
            public double min { get; set; }
            public double max { get; set; }
            public double night { get; set; }
            public double eve { get; set; }
            public double morn { get; set; }
        }
    
        public class Weather
        {
            public int id { get; set; }
            public string main { get; set; }
            public string description { get; set; }
            public string icon { get; set; }
        }
    
        public class List
        {
            public int dt { get; set; }
            public Temp temp { get; set; }
            public double pressure { get; set; }
            public int humidity { get; set; }
            public List<Weather> weather { get; set; }
            public double speed { get; set; }
            public int deg { get; set; }
            public int clouds { get; set; }
            public double snow { get; set; }
            public double? rain { get; set; }
        }
    
        public class RootObject
        {
            public string cod { get; set; }
            public double message { get; set; }
            public City city { get; set; }
            public int cnt { get; set; }
            public List<List> list { get; set; }
        }
    }
    

    8 декабря 2014 г. 10:32
  • А можете объяснить, почему мы делаем десереализацию RootObject?
    12 декабря 2014 г. 8:21
  • А можете объяснить, почему мы делаем десереализацию RootObject?

    Да.

    Открываете JSON. Копируете его сюда(json2sharp). Получаем модельки. 

    Смотрим, у нас появился RootObject, а все остальные имеют нормальные названия. Почему? Потому что у него и нет названия. Json начинается с пары фигурных скобок. Это и есть RootObject.

    Так же для удобства я смотрю JSON через Json Editor Online

    Никто не заставляет называть его RootObject. Переименуйте как Вам хочется.

    Теперь насчет именование свойств - они здесь все с маленькой буквы. Можно сделать маппинг для удобства, что бы не привязываться к тем именам, которые в JSON.

    [JsonProperty(PropertyName = "speed")]
    public double Speed { get; set; }


    • Предложено в качестве ответа Mykyta Bondarenko 12 декабря 2014 г. 21:13
    • Помечено в качестве ответа Dmitrii Shimanov 16 декабря 2014 г. 16:53
    12 декабря 2014 г. 9:51