如何解析json并将其反序列化为类的ObservableCollection

问题描述

我正在构建一个 Xamarinforms 应用程序,该应用程序使用 Web 服务 api 来填充权力的游戏中的数据。 API 将在应用中填写演员姓名、图片和舞台名称

我正在努力 解析 json 并将其反序列化为 CharacterClass 的 ObservableCollection (从这个函数返回 Task

这是我得到的错误

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型“System.Collections.ObjectModel.ObservableCollection`1[GOTapp.CharacterClass]”,因为该类型需要一个 JSON 数组(例如 [1,2,3]) 以正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 数组(例如 [1,3])或更改反序列化类型,使其成为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像这样的集合类型)可以从 JSON 对象反序列化的数组或列表)。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。 路径“字符”,第 2 行,位置 16。

namespace GOTapp
{
    public class CharactersManager
    {
        public ObservableCollection<CharacterClass> characterList
        {
            get;
            set;
        }

    public class LogInResult
    {
        public string Name { get; set; }
        public string cityName { get; set; }
        public string img { get; set; }
        public string usrId { get; set; }
    }

    public string url = "https://raw.githubusercontent.com/jeffreylancaster/game-of-thrones/master/data/characters.json";
    HttpClient client = new HttpClient();


    public async Task<ObservableCollection<CharacterClass>> downloadData()
    {
        // Get data from provided web service
        // parse json and deserialize it to ObservableCollection of CharacterClass
        // return Task<ObservableCollection<CharacterClass>> from this function





        var json = await client.GetStringAsync(url);
        characterList = JsonConvert.DeserializeObject<ObservableCollection<CharacterClass>>(json);

        return characterList;
    }
    

    public void postActor()
    {
        var character = new CharacterClass
        {
            characterImageThumb = "https://images-na.ssl-images-amazon.com/images/M/MV5BNzI5MDg0ZDAtN2Y2ZC00MzU1LTgyYjQtNTBjYjEzODczZDVhXkEyXkFqcGdeQXVyNTg0Nzg4NTE@._V1._SX100_SY140_.jpg",characterName = "Aeron Greyjoy",actorName = "Michael Feast"
        };


        var content = JsonConvert.SerializeObject(character);
        client.PostAsync(url,new StringContent(content));

    }



}

}

这里是json的格式

{
   "characters":[
      {
         "characterName":"Addam Marbrand","characterLink":"/character/ch0305333/","actorName":"B.J. Hogg","actorLink":"/name/nm0389698/"
      },{
         "characterName":"Aegon Targaryen","houseName":"Targaryen","royal":true,"parents":[
            "Elia Martell","Rhaegar Targaryen"
         ],"siblings":[
            "Rhaenys Targaryen","Jon SNow"
         ],"killedBy":[
            "Gregor Clegane"
         ]
      }
]
}

这里是json数据的链接 https://raw.githubusercontent.com/jeffreylancaster/game-of-thrones/master/data/characters.json

我希望得到任何形式的帮助

这是我的主页

namespace GOTapp

{ 公共部分类 MainPage : ContentPage {

    public ObservableCollection<CharacterClass> downloadedList;

    public CharactersManager manager = new CharactersManager();

    public MainPage()
    {
        InitializeComponent();
        actorlist.RowHeight = 50;

    }

    protected async override void OnAppearing()
    {
        if (downloadedList.Count == 0)
        {
            actorlist.ItemsSource = null;
            // call downloadData function from here.
            var list = await manager.downloadData();
            downloadedList = new ObservableCollection<CharacterClass>(list);
            actorlist.ItemsSource = downloadedList;
            

        }
        base.OnAppearing();
    }

    void actorlist_ItemSelected(System.Object sender,Xamarin.Forms.selecteditemchangedEventArgs e)
    {
        // navigate to Detail Page and passing the selected character to detail page.

        manager.postActorList();
    }

}

}

这是我的。字符类.cs

   using System;
namespace GOTapp
{
    public class CharacterClass
    {
        public int id { get; set; }
        public string characterName { get; set; }
        public string actorName { get; set; }
        public string characterImageThumb { get; set; }





        public CharacterClass()
        {

        }
        
        // Version 2: add integer attribute for rating.
    }
}

解决方法

您可以使用以下代码。

var characterList = JsonConvert.DeserializeObject<Example>(json);
ObservableCollection<CharacterClass> myCollection = new ObservableCollection<CharacterClass>(characterList.characters);

public class Example
{
    public IList<CharacterClass> characters { get; set; }
}
,

Json 的数据有一个非常烦人的问题。 HouseName 值具有字符串值和字符串数组值。我把它变成了一个对象,然后给它两个单独的变量 StringHouseNameArrayHouseName 每个记录中只有一个有值。

1.必修课

public class DataWeb
{
    public ObservableCollection<CharacterClass> Characters { get; set; }
}
public class CharacterClass
{
    public int id { get; set; }
    public string CharacterName { get; set; }
    public string StringHouseName { get; set; }
    public string[] ArrayHouseName { get; set; }
    public object HouseName
    {
       get
       {
          if (string.IsNullOrEmpty(StringHouseName))
             return ArrayHouseName;
          else
             return StringHouseName;
       }
       set
       {
           if (value is JArray)
           {
               JArray jArray = (JArray)value;
               ArrayHouseName = jArray.Select(ja => (string)ja).ToArray();
           }   
           else
               StringHouseName = (string)value;
       }
   }
   public string CharacterImageThumb { get; set; }
   public string CharacterImageFull { get; set; }
   public string CharacterLink { get; set; }
   public string ActorName { get; set; }
   public string ActorLink { get; set; }
   public bool kingsguard { get; set; }
   public bool Royal { get; set; }
   public string[] killedBy { get; set; }
   public string[] ParentOf { get; set; }

   public string[] Serves { get; set; }
   public string[] Siblings { get; set; }
   public string[] Killed { get; set; }
   public string[] Parents { get; set; }
   public string[] GuardedBy { get; set; }
   public string[] MarriedEngaged { get; set; }
   public string[] GuardianOf { get; set; }
   public string[] Allies { get; set; }
   public Actor[] Actors { get; set; }
}
public class Actor
{
    public string ActorName { get; set; }
    public string ActorLink { get; set; }
    public int[] SeasonsActive { get; set; }
}

2.现在使用和反序列化

public async Task<ObservableCollection<CharacterClass>> downloadData()
{
    var client = new HttpClient();
    var result = await client.GetAsync(@"https://raw.githubusercontent.com/jeffreylancaster/game-of-thrones/master/data/characters.json");
    var json = await result.Content.ReadAsStringAsync();

    DataWeb dataWeb = JsonConvert.DeserializeObject<DataWeb>(json);
    return dataWeb.Characters;
}

private async void button1_Click(object sender,EventArgs e)
{
   await Task.Run(() =>
   {
      var gameOfThrones = downloadData().Result;
   });
}