Невозможно десериализовать текущий объект JSON xamarin.forms

Я использую xamarin.forms для создания приложения, использующего MusixMatch api. Это вызывает следующее исключение: Невозможно десериализовать текущий объект JSON (например, {\ "name \": \ "value \"}) в тип 'System.Collections.Generic.List. Насколько мне известно, я все сделал правильно, не знаю, почему возникает это исключение. Любая помощь будет оценена по достоинству.

TrackList.cs

public class TrackList
    {
        public class Track
        {
            public int track_id { get; set; }
            public string track_mbid { get; set; }
            public string track_isrc { get; set; }
            public string track_spotify_id { get; set; }
            public string track_soundcloud_id { get; set; }
            public string track_xboxmusic_id { get; set; }
            public string track_name { get; set; }
            public int track_rating { get; set; }
            public int track_length { get; set; }
            public int commontrack_id { get; set; }
            public int instrumental { get; set; }
        }
        public class Body
        {
            public IList<Track> track_list { get; set; }
        }

    }

Запрос API

public async void SearchBtn(object sender, EventArgs e)
        {
            List<TrackList.Track> trans = new List<TrackList.Track>();
            string search = SearchField.Text;
            try
            {
                var content = "";
                HttpClient client = new HttpClient();

                var RestUrl = "http://api.musixmatch.com/ws/1.1/track.search?q_track = " + search + "&page_size=3&page=1&s_track_rating=desc";
                client.BaseAddress = new Uri(RestUrl);

                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = await client.GetAsync(RestUrl);
                content = await response.Content.ReadAsStringAsync();

                var items = JsonConvert.DeserializeObject<List<TrackList.Body>>(content);
                listTracks.ItemsSource = items;

            }
            catch (Exception ex)
            {
                string exception = ex.Message;
            }
        }

JSON от PostMan

{
    "message": {
        "header": {
            "status_code": 200,
            "execute_time": 0.013219118118286,
            "available": 10000
        },
        "body": {
            "track_list": [
                {
                    "track": {
                        "track_id": 143296606,
                        "track_mbid": "",
                        "track_isrc": "",
                        "track_spotify_id": "",
                        "track_soundcloud_id": "",
                        "track_xboxmusic_id": "",
                        "track_name": "&Burn",
                        "track_name_translation_list": [],
                        "track_rating": 61,
                        "track_length": 179,
                        "commontrack_id": 79313332,
                        "instrumental": 0,
                        "explicit": 0,
                        "has_lyrics": 1,
                        "has_lyrics_crowd": 0,
                        "has_subtitles": 1,
                        "has_richsync": 1,
                        "num_favourite": 19,
                        "lyrics_id": 17324950,
                        "subtitle_id": 19405016,
                        "album_id": 27788309,
                        "album_name": "Dont Smile At Me",
                        "artist_id": 34955086,
                        "artist_mbid": "",
                        "artist_name": "Billie Eilish feat. Vince Staples",
                        "album_coverart_100x100": "http://s.mxmcdn.net/images-storage/albums/nocover.png",
                        "album_coverart_350x350": "",
                        "album_coverart_500x500": "",
                        "album_coverart_800x800": "",
                        "track_share_url": "https://www.musixmatch.com/lyrics/Billie-Eilish-feat-Vince-Staples/burn-with-Vince-Staples?utm_source=application&utm_campaign=api&utm_medium=IT+Related%3A1409617652911",
                        "track_edit_url": "https://www.musixmatch.com/lyrics/Billie-Eilish-feat-Vince-Staples/burn-with-Vince-Staples/edit?utm_source=application&utm_campaign=api&utm_medium=IT+Related%3A1409617652911",
                        "commontrack_vanity_id": "Billie-Eilish-feat-Vince-Staples/burn-with-Vince-Staples",
                        "restricted": 0,
                        "first_release_date": "2017-12-15T00:00:00Z",
                        "updated_time": "2017-12-17T22:53:56Z",
                        "primary_genres": {
                            "music_genre_list": []
                        },
                        "secondary_genres": {
                            "music_genre_list": []
                        }
                    }
                }
            ]
        }
    }
}

Вы только что разместили свой ключ API на общедоступном веб-сайте? Может быть, это не лучший вариант :) Обычно я начинаю с app.quicktype.io и позволяю сгенерировать класс, а затем меняю имя так, как я хочу.

Gerald Versluis 11.04.2018 12:00

Ой, забыл об этом. Спасибо. Попробую ваше предложение

Janine Alexander 11.04.2018 12:04

Ваш ключ api все еще находится в истории вопросов.

fredrik 11.04.2018 12:48

Похоже, что тип, который вы пытаетесь сериализовать, не соответствует структуре JSON.

fredrik 11.04.2018 12:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
627
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, вы не можете десериализовать один объект в коллекцию. Поэтому вам следует использовать TrackList.Body вместо List<TrackList.Body>.

Так что вам, возможно, придется изменить эту строку:

var items = JsonConvert.DeserializeObject<List<TrackList.Body>>(content);

к

var items = JsonConvert.DeserializeObject<TrackList.Body>(content);

затем повторите каждый элемент в items, чтобы добавить их в List<TrackList.Body>

Спасибо. Я пробовал это, исключение исчезло, но теперь «items» возвращает null, хотя при отладке я вижу, что статус ответа равен 200 и передается в «content»

Janine Alexander 11.04.2018 12:40

Я обновил свой пост, включив json для лучшего понимания

Janine Alexander 11.04.2018 12:43
Ответ принят как подходящий

Вы говорите ему десериализовать результат в список, когда на самом деле результатом является объект с 1 свойством (сообщением), который имеет 2 свойства (заголовок и тело), ​​поэтому убедитесь, что структура вашего объекта совпадает. Я считаю, что json2csharp чрезвычайно удобен для таких сложных структур.

public class TrackListResponse
{
    public Message message { get; set; }

    public class Header
    {
        public int status_code { get; set; }
        public double execute_time { get; set; }
        public int available { get; set; }
    }

    public class PrimaryGenres
    {
        public List<object> music_genre_list { get; set; }
    }

    public class SecondaryGenres
    {
        public List<object> music_genre_list { get; set; }
    }

    public class Track
    {
        public int track_id { get; set; }
        public string track_mbid { get; set; }
        public string track_isrc { get; set; }
        public string track_spotify_id { get; set; }
        public string track_soundcloud_id { get; set; }
        public string track_xboxmusic_id { get; set; }
        public string track_name { get; set; }
        public List<object> track_name_translation_list { get; set; }
        public int track_rating { get; set; }
        public int track_length { get; set; }
        public int commontrack_id { get; set; }
        public int instrumental { get; set; }
        public int @explicit { get; set; }
        public int has_lyrics { get; set; }
        public int has_lyrics_crowd { get; set; }
        public int has_subtitles { get; set; }
        public int has_richsync { get; set; }
        public int num_favourite { get; set; }
        public int lyrics_id { get; set; }
        public int subtitle_id { get; set; }
        public int album_id { get; set; }
        public string album_name { get; set; }
        public int artist_id { get; set; }
        public string artist_mbid { get; set; }
        public string artist_name { get; set; }
        public string album_coverart_100x100 { get; set; }
        public string album_coverart_350x350 { get; set; }
        public string album_coverart_500x500 { get; set; }
        public string album_coverart_800x800 { get; set; }
        public string track_share_url { get; set; }
        public string track_edit_url { get; set; }
        public string commontrack_vanity_id { get; set; }
        public int restricted { get; set; }
        public DateTime first_release_date { get; set; }
        public DateTime updated_time { get; set; }
        public PrimaryGenres primary_genres { get; set; }
        public SecondaryGenres secondary_genres { get; set; }
    }

    public class TrackList
    {
        public Track track { get; set; }
    }

    public class Body
    {
        public List<TrackList> track_list { get; set; }
    }

    public class Message
    {
        public Header header { get; set; }
        public Body body { get; set; }
    }
}

Затем просто десериализуйте внешний объект:

JsonConvert.DeserializeObject<TrackListResponse>(content);

Спасибо :). Я пробовал это, но свойства возвращают null в «items», но значения успешно передаются в «content».

Janine Alexander 11.04.2018 13:11

Возможно, в первый раз я ошибся с телом. Ответ обновлен - на помощь приходит json2csharp. :)

Todd Menier 11.04.2018 13:12

Большое спасибо Тодду: D. Теперь это работает. Просто свойства сейчас не привязаны к моему xaml, но я разберусь с этим. Спасибо

Janine Alexander 11.04.2018 13:40

Другие вопросы по теме