JSON无法反序列化Xamarin Weather App

时间:2019-02-10 09:39:20

标签: c# json xamarin xamarin.forms

我正在学习如何在Xamarin中执行列表,我从昨天开始,并且还有几天要完成的工作。当我在Android上运行新程序时,我的第一个应用程序运行良好,但第二个应用程序运行良好,但第二个应用程序(主要基于第一个应用程序,我上了1:30小时的课程,并且学习的时间不多)无法反序列化的错误。

我很确定我的错误是在MainPage.xaml.cs

meteo0.cs(第8至26行)

public class Meteo0
{
    public string precipitaProb { get; set; }
    public int tMin { get; set; }
    public int tMax { get; set; }
    public string predWindDir { get; set; }
    public int idWeatherType { get; set; }
    public int classWindSpeed { get; set; }
    public string longitude { get; set; }
    public int classPrecInt { get; set; }
    public int globalIdLocal { get; set; }
    public string latitude { get; set; }
    public string owner { get; set; }
    public string country { get; set; }
    public string forecastDate { get; set; }
    public List<Meteo0> data { get; set; }
    public DateTime dataUpdate { get; set; }
}

MainPage.xaml.cs(第10到39行)

public partial class MainPage : ContentPage
{
    const string Url = "https://api.ipma.pt/open-data/forecast/meteorology/cities/daily/1110600";

    public MainPage()
    {
        InitializeComponent();
    }
    protected override void OnAppearing()
    {
        GetMeteo0();
        base.OnAppearing();
    }
    async void GetMeteo0()
    {
        List<Meteo0> meteo0;
        HttpClient httpClient = new HttpClient();
        var content = await httpClient.GetStringAsync(Url);
        meteo0 = JsonConvert.DeserializeObject<List<Meteo0>>(content);
        meteo0ListView.ItemsSource = meteo0;
    }
    private void meteo0ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        Meteo0 meteo0 = e.SelectedItem as Meteo0;
        Navigation.PushAsync(new MeteoDetails(meteo0));
    }
}

编辑过的MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    const string Url = "https://api.ipma.pt/open-data/forecast/meteorology/cities/daily/1110600";

    public MainPage()
    {
        InitializeComponent();
    }
    protected override void OnAppearing()
    {
        GetMeteo0();
        base.OnAppearing();
    }
    async void GetMeteo0()
    {
        List<Meteo0> meteo0;
        HttpClient httpClient = new HttpClient();
        var content = await httpClient.GetStringAsync(Url);
        var result = JsonConvert.DeserializeObject<RootObject>(content);
        meteo0ListView.ItemsSource = result.data;
    }
    private void meteo0ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        Meteo0 meteo0 = e.SelectedItem as Meteo0;
        Navigation.PushAsync(new MeteoDetails(meteo0));
    }
}

编辑的meteo0.cs

public class Meteo0
{
    public string precipitaProb { get; set; }
    public double tMin { get; set; }
    public double tMax { get; set; }
    public string predWindDir { get; set; }
    public int idWeatherType { get; set; }
    public int classWindSpeed { get; set; }
    public string longitude { get; set; }
    public int classPrecInt { get; set; }
    public int globalIdLocal { get; set; }
    public string latitude { get; set; }
}

新的RootObject.cs

public class RootObject
{
    public string owner { get; set; }
    public string country { get; set; }
    public string forecastDate { get; set; }
    public List<Meteo0> data { get; set; }
    public DateTime dataUpdate { get; set; }
}

MainPage.xaml

<ListView x:Name="meteo0ListView" ItemSelected="meteo0ListView_ItemSelected">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextCell Text="Weather"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

1 个答案:

答案 0 :(得分:0)

如果查看从服务器收到的Json结果,您会发现它实际上不是根目录中的列表。即使数据点列表实际上是根对象中的一个属性,您想要做的就是将单个对象投射到List中。

{  
   "owner":"IPMA",
   "country":"PT",
   "data":[  
      {  
         "precipitaProb":"79.0",
         "tMin":"11.3",
         "tMax":"17.7",
         "predWindDir":"SW",
         "idWeatherType":7,
         "classWindSpeed":2,
         "longitude":"-9.1286",
         "forecastDate":"2019-02-10",
         "classPrecInt":1,
         "latitude":"38.7660"
      },
      {  
         "precipitaProb":"0.0",
         "tMin":"9.6",
         "tMax":"17.0",
         "predWindDir":"N",
         "idWeatherType":1,
         "classWindSpeed":1,
         "longitude":"-9.1286",
         "forecastDate":"2019-02-11",
         "latitude":"38.7660"
      }
      // ...
   ],
   "globalIdLocal":1110600,
   "dataUpdate":"2019-02-10T11:31:03"
}

知道这一点,您可能应该有两个类,主要的一个包含数据点列表。像这样:

public class WeatherResult {
    public string owner {get; set; }
    public string country {get; set; }
    public List<Meteo0> data { get; set; }
    // ...
}

然后,您应将其反序列化,而不要反序列化Meteo0实体列表。

var result = JsonConvert.DeserializeObject<WeatherResult>(content);

此后,通过引用result.data,可以轻松地将Meteo0对象的列表用作ItemsSource。

顺便说一句,正如您从数据中看到的那样,tMin和tMax字段不是整数类型,因为它们中包含十进制值。您也必须修复该问题。

相关问题