如何从GET请求中反序列化JSON并将其显示在Xamarin中的ListView上

时间:2018-11-19 02:32:16

标签: c# json rest xamarin.forms json.net

我正在尝试从REST Api响应中反序列化JSON字符串,然后在Xamarin.forms中的ListView上显示它。这是到目前为止我得到的:

-TheMainPage.xaml.cs,在此我连接到api并(应该)反序列化响应。

-MainPage.xaml,我在其中创建了要显示的ListView。

-UserModel.cs,用于存储我从API接收的JSON模型(在此处粘贴JSON:https://app.quicktype.io/以获得类)。

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

要反序列化的示例JSON

{
  "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"
  } ]
}

但是当我运行程序时,出现以下错误:Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'RESTListView.Users[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. 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 [异常图片]

在实现此目标方面的任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

您的ItemsSource必须是IEnumerable(即集合或列表)。

Users model = Users.FromJson(json);

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

MyListView.ItemsSource = users;

答案 1 :(得分:0)

尝试像这样的列表视图绑定:

Users model = Users.FromJson(json);

MyListView.ItemsSource = model.Data;

并替换您的局部类,例如:

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