Cannot deserialize the current JSON object xamarin

2019-08-22 00:16发布

Im using xamarin.forms to create an app that uses the MusixMatch api. It's throwing the following exception : Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List. To my knowledge, Ive done everything correctly, not sure why this exception is being thrown. Any help will be appreciated.

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 Request

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

The json from 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": []
                        }
                    }
                }
            ]
        }
    }
}

2条回答
一夜七次
2楼-- · 2019-08-22 00:31

I think you can't deserialize a single object into a collection. So you should use TrackList.Body instead of List<TrackList.Body>

So you maybe have to change this line:

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

to

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

then iterate each item in items to add them to a List<TrackList.Body>

查看更多
何必那么认真
3楼-- · 2019-08-22 00:46

You're telling it to deserialize the result to a list, when actually the result is object with 1 property (message) which has 2 properties (header and body), so make sure your object structure matches. I find json2csharp extremely handy for complex structures like this.

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

Then just deserialize to the outer object:

JsonConvert.DeserializeObject<TrackListResponse>(content);
查看更多
登录 后发表回答