简体   繁体   English

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

[英]How to parse json and deserialize it to ObservableCollection of a class

I am building a Xamarinforms app that uses a webservice api to fill data in with game of throne cast.我正在构建一个 Xamarinforms 应用程序,该应用程序使用网络服务 api 来填充数据与王座演员的游戏。 The API will fill in the app with the actors name,picture and stageName. API 将在应用程序中填写演员姓名、图片和舞台名称。

I am trying to parse json and deserialize it to ObservableCollection of CharacterClass (return Task<ObservableCollection> from this function)我正在尝试解析 json 并将其反序列化为 CharacterClass 的 ObservableCollection(从此函数返回 Task<ObservableCollection>)

This is the error I get这是我得到的错误

Cannot deserialize the current JSON object (eg {"name":"value"}) into type 'System.Collections.ObjectModel.ObservableCollection`1[GOTapp.CharacterClass]' because the type requires a JSON array (eg [1,2,3]) to deserialize correctly. Cannot deserialize the current JSON object (eg {"name":"value"}) into type 'System.Collections.ObjectModel.ObservableCollection`1[GOTapp.CharacterClass]' because the type requires a JSON array (eg [1,2, 3])正确反序列化。 To fix this error either change the JSON to a JSON array (eg [1,2,3]) or change the deserialized type so that it is a normal .NET type (eg not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. To fix this error either change the JSON to a JSON array (eg [1,2,3]) or change the deserialized type so that it is a normal .NET type (eg not a primitive type like integer, not a collection type like an数组或列表)可以从 JSON object 反序列化。 JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. JsonObjectAttribute 也可以添加到类型中以强制它从 JSON object 反序列化。 Path 'characters', line 2, position 16.路径“字符”,第 2 行,position 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));

    }



}

} }

Here is the format of the json这是 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"
         ]
      }
]
}

here is the link for the json data https://raw.githubusercontent.com/jeffreylancaster/game-of-thrones/master/data/characters.json这是 json 数据https://raw.githubusercontent.com/jeffreylancaster/game-of-thrones/master/data/characters.Z466DEEC76ECDF5FCA6D38571F6324D5Z4的链接

I would appreciate any form of assistance我将不胜感激任何形式的帮助

this is my mainPage这是我的主页

namespace GOTapp

{ public partial class MainPage: ContentPage { {公共部分class 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();
    }

}

} }

this is my.这是我的。 charactar class.cs字符 class.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.
    }
}

You can use the below code.您可以使用以下代码。

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

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

Json's data had a really annoying problem. Json 的数据有一个非常烦人的问题。 The HouseName value has both a string value and an array value of strings. HouseName值具有字符串值和字符串数组值。 I turned it into an object and then gave it two separate variables StringHouseName And ArrayHouseName Only one of them has a value in each record.我把它变成了一个 object 然后给它两个单独的变量StringHouseNameArrayHouseName每个记录中只有一个有一个值。

1. required Classes 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. Now use and deserialize 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;
   });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM