无法反序列化当前 JSON 对象 xamarin.forms

Posted

技术标签:

【中文标题】无法反序列化当前 JSON 对象 xamarin.forms【英文标题】:Cannot deserialize the current JSON object xamarin.forms 【发布时间】:2018-04-11 09:57:00 【问题描述】:

我正在使用 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;
            
        

来自 PostMan 的 json


    "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 开始,然后生成一个类,然后按照我想要的方式更改命名 糟糕,忘记了。感谢你。会尝试你的建议 您的 api 密钥仍在问题历史记录中。 看起来您尝试序列化的类型与 JSON 结构不匹配。 【参考方案1】:

您告诉它将结果反序列化为列表,而实际上结果是具有 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,但值已成功传递给“内容” 我第一次可能把 body 对象弄错了一点。答案已更新 - json2csharp 来救援。 :) 非常感谢托德:D。现在可以了。只是属性现在没有绑定到我的 xaml,但我会弄清楚的。谢谢【参考方案2】:

我认为您不能将单个对象反序列化为集合。所以你应该使用TrackList.Body 而不是List&lt;TrackList.Body&gt;

所以你可能不得不改变这一行:

var items = JsonConvert.DeserializeObject&lt;List&lt;TrackList.Body&gt;&gt;(content);

var items = JsonConvert.DeserializeObject&lt;TrackList.Body&gt;(content);

然后迭代items 中的每个项目以将它们添加到List&lt;TrackList.Body&gt;

【讨论】:

谢谢。我已经尝试过了,异常消失了,但现在“items”返​​回 null,即使在调试时我可以看到响应状态为 200 并传递给“content” 我已经更新了我的帖子以包含 json 以便更好地理解

以上是关于无法反序列化当前 JSON 对象 xamarin.forms的主要内容,如果未能解决你的问题,请参考以下文章

无法反序列化当前的JSON对象,为啥

Json.JsonSerializationException : 无法反序列化当前 JSON 对象

Xamarin 表单反序列化 Json 不工作

Blazor WASM“无法反序列化当前 JSON 对象(例如 "name":"value")”错误

无法将当前 JSON 数组(例如 [1,2,3])反序列化为具有复杂和嵌套对象的类型

发布关系数据时无法反序列化当前的JSON对象