简体   繁体   中英

How to deserialize JSON from a GET request and display it on a ListView in Xamarin

I am trying to deserialize a JSON string from a REST Api response and then show it on a ListView in Xamarin.forms. This is what I got so far:

-TheMainPage.xaml.cs where I connect to the api and (should) deserialize the response.

-The MainPage.xaml where I created the ListView for display.

-The UserModel.cs where I stored the model for the JSON I am receiving from the API (Pasted the JSON here: https://app.quicktype.io/ to get the class).

MainPage.xaml.cs

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using RESTListView;


namespace RESTListViewApp
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            GETRequest();
        }

        private async void GETRequest()
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "dXNlcjQyMzIxNTQwMzMwMjI0OmE2YTZjZDMyLWQ4NTItNGZlNS04NmMxLWE3NTFhMWUyNmZlNA==");

            string url = "https://shared-sandbox-api.marqeta.com/v3/users";

            var result = await client.GetAsync(url);
            var json = result.Content.ReadAsStringAsync().Result;

            Users model = Users.FromJson(json);

            MyListView.ItemsSource = model;
        }

    }
}

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:RESTListViewApp"
             x:Class="RESTListViewApp.MainPage">


    <StackLayout>
        <StackLayout HorizontalOptions="Center">
            <Button Text="ADD"/>
            <Button Text="DELETE"/>
        </StackLayout>
        <ListView x:Name="MyListView" HasUnevenRows="True">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout HorizontalOptions="Center">
                            <Label Text="{Binding Token}"/>
                            <Label Text="{Binding FirstName}"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </StackLayout>

</ContentPage>

UserModel.cs

    // <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using RESTListView;
//
//    var users = Users.FromJson(jsonString);

namespace RESTListView
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class Users
    {
        [JsonProperty("count")]
        public long Count { get; set; }

        [JsonProperty("start_index")]
        public long StartIndex { get; set; }

        [JsonProperty("end_index")]
        public long EndIndex { get; set; }

        [JsonProperty("is_more")]
        public bool IsMore { get; set; }

        [JsonProperty("data")]
        public Datum[] Data { get; set; }
    }

    public partial class Datum
    {
        [JsonProperty("token")]
        public string Token { get; set; }

        [JsonProperty("active")]
        public bool Active { get; set; }

        [JsonProperty("first_name", NullValueHandling = NullValueHandling.Ignore)]
        public string FirstName { get; set; }

        [JsonProperty("email")]
        public string Email { get; set; }

        [JsonProperty("phone", NullValueHandling = NullValueHandling.Ignore)]
        public string Phone { get; set; }

        [JsonProperty("parent_token", NullValueHandling = NullValueHandling.Ignore)]
        public Guid? ParentToken { get; set; }

        [JsonProperty("uses_parent_account")]
        public bool UsesParentAccount { get; set; }

        [JsonProperty("corporate_card_holder")]
        public bool CorporateCardHolder { get; set; }

        [JsonProperty("company", NullValueHandling = NullValueHandling.Ignore)]
        public string Company { get; set; }

        [JsonProperty("created_time")]
        public DateTimeOffset CreatedTime { get; set; }

        [JsonProperty("last_modified_time")]
        public DateTimeOffset LastModifiedTime { get; set; }

        [JsonProperty("business_token", NullValueHandling = NullValueHandling.Ignore)]
        public Guid? BusinessToken { get; set; }

        [JsonProperty("metadata")]
        public Metadata Metadata { get; set; }

        [JsonProperty("account_holder_group_token")]
        public string AccountHolderGroupToken { get; set; }

        [JsonProperty("status")]
        public string Status { get; set; }
    }

    public partial class Metadata
    {
    }

    public partial class Users
    {
        public static Users FromJson(string json) => JsonConvert.DeserializeObject<Users>(json, RESTListView.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Users self) => JsonConvert.SerializeObject(self, RESTListView.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
}

Example JSON to deserialize

{
  "count" : 5,
  "start_index" : 0,
  "end_index" : 4,
  "is_more" : true,
  "data" : [ {
    "token" : "9dd1c8bd-9de8-4c36-8f33-d088f843b053",
    "active" : true,
    "first_name" : "Dhd Fh",
    "email" : "TEMPORARY_5cab6e5f-8d8c-44f2-aa4a-ad3d1caed890_ffg@ff.gg",
    "phone" : "+375291766633",
    "parent_token" : "1074bcd0-8e92-4158-8edf-71b6039c7059",
    "uses_parent_account" : true,
    "corporate_card_holder" : false,
    "company" : " fggg",
    "created_time" : "2018-11-19T07:11:33Z",
    "last_modified_time" : "2018-11-19T07:11:33Z",
    "business_token" : "1074bcd0-8e92-4158-8edf-71b6039c7059",
    "metadata" : { },
    "account_holder_group_token" : "DEFAULT_AHG",
    "status" : "ACTIVE"
  }, {
    "token" : "c26623b3-e1ac-47d5-82b5-890771cb5450",
    "active" : true,
    "first_name" : "Dhd Fh",
    "email" : "TEMPORARY_2f34b134-1b76-4a69-a4c3-945d971cf70a_fud@dhd.dhd",
    "phone" : "+375291766633",
    "parent_token" : "85b279c6-4c3a-45cd-8a8c-c7c361f5b413",
    "uses_parent_account" : true,
    "corporate_card_holder" : false,
    "company" : "fjf",
    "created_time" : "2018-11-19T07:07:33Z",
    "last_modified_time" : "2018-11-19T07:07:33Z",
    "business_token" : "85b279c6-4c3a-45cd-8a8c-c7c361f5b413",
    "metadata" : { },
    "account_holder_group_token" : "DEFAULT_AHG",
    "status" : "ACTIVE"
  }, {
    "token" : "B$_C_zlq3yedu",
    "active" : true,
    "email" : "B$_C_zlq3yedu@square.invalid",
    "uses_parent_account" : false,
    "corporate_card_holder" : false,
    "created_time" : "2018-11-19T05:16:52Z",
    "last_modified_time" : "2018-11-19T05:16:52Z",
    "metadata" : { },
    "account_holder_group_token" : "DEFAULT_AHG",
    "status" : "ACTIVE"
  }, {
    "token" : "B$_C_svutldl3",
    "active" : true,
    "email" : "B$_C_svutldl3@square.invalid",
    "uses_parent_account" : false,
    "corporate_card_holder" : false,
    "created_time" : "2018-11-19T04:50:18Z",
    "last_modified_time" : "2018-11-19T04:50:18Z",
    "metadata" : { },
    "account_holder_group_token" : "DEFAULT_AHG",
    "status" : "ACTIVE"
  }, {
    "token" : "B$_C_4wzzylny",
    "active" : true,
    "email" : "B$_C_4wzzylny@square.invalid",
    "uses_parent_account" : false,
    "corporate_card_holder" : false,
    "created_time" : "2018-11-19T04:11:13Z",
    "last_modified_time" : "2018-11-19T04:11:13Z",
    "metadata" : { },
    "account_holder_group_token" : "DEFAULT_AHG",
    "status" : "ACTIVE"
  } ]
}

But when I run the program I get this error: Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (eg {"name":"value"}) into type 'RESTListView.Users[]' because the type requires a JSON array (eg [1,2,3]) to deserialize correctly.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<T>) that can be deserialized from a JSON object.

https://i.stack.imgur.com/dtxr5.png [Exception Image]

Any help on how to achieve this would be appreciated.

your ItemsSource must be an IEnumerable (ie, a collection or list).

Users model = Users.FromJson(json);

List<Users> users = new List<Users>();
users.Add(model);

MyListView.ItemsSource = users;

Try listview binding like :

Users model = Users.FromJson(json);

MyListView.ItemsSource = model.Data;

And Replace your partial class like:

 public partial class Users
{
    [JsonProperty("count")]
    public long Count { get; set; }

    [JsonProperty("start_index")]
    public long StartIndex { get; set; }

    [JsonProperty("end_index")]
    public long EndIndex { get; set; }

    [JsonProperty("is_more")]
    public bool IsMore { get; set; }

    [JsonProperty("data")]
    public List<Datum> Data { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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