【问题标题】:Issues with binding xaml with json serialization将 xaml 与 json 序列化绑定的问题
【发布时间】:2021-07-21 17:29:18
【问题描述】:

我在我的 xamarin 表单 .xaml 中使用 json 序列化的 REST API 显示数据时遇到问题。

Console.WriteLine("测试产品:" + ProductList.Count);确实返回了产品列表 (55) 但它没有查看。

我也有这个错误

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

我不知道是什么问题。

RESTAPIService.cs

public RestAPIService()
{
   client = new HttpClient { BaseAddress = new Uri("https://xxx.xxxxxxx.xx/xx/") };

   client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

}

public async Task<ObservableCollection<Products>> GetProducts()
{
   products = new ObservableCollection<Products>();

   var token = SecureStorage.GetAsync("AuthKey");

   client.DefaultRequestHeaders.Add("www-authentication", await token);
            
    try
    {
     HttpResponseMessage response = await client.GetAsync("products");
     if (response.IsSuccessStatusCode)
        {
          var content = await response.Content.ReadAsStringAsync();
          products = JsonConvert.DeserializeObject<ObservableCollection<Products>>(content);
          Console.WriteLine("response products: " + products.Count);

           }
      }
            catch (Exception ex)
            {
                Debug.WriteLine(@"\tERROR {0}", ex.Message);
            }

            return products;
        }

Products.cs我的模态类

    public class ImageFront
    {
        public string extension { get; set; }
        public string name { get; set; }
        public string contents { get; set; }
        public int size { get; set; }
        public string date { get; set; }
        public object thumb { get; set; }
        public int? width { get; set; }
        public int? height { get; set; }
    }

    public class ImageThumb
    {
        public string extension { get; set; }
        public string name { get; set; }
        public string contents { get; set; }
        public int size { get; set; }
        public string date { get; set; }
        public object thumb { get; set; }
        public int? width { get; set; }
        public int? height { get; set; }
    }

    public class File
    {
        public string extension { get; set; }
        public string name { get; set; }
        public string contents { get; set; }
        public int size { get; set; }
        public string date { get; set; }
    }

    public class Product
    {
        public string id { get; set; }
        public string number { get; set; }
        public string name { get; set; }
        public string indication { get; set; }
        public string weight { get; set; }
        public string amount { get; set; }
        public string kind { get; set; }
        public string usage_days { get; set; }
        public string usage_dosage { get; set; }
        public string usage_how { get; set; }
        public string dosage { get; set; }
        public string allergie { get; set; }
        public string nutrition { get; set; }
        public string preserve { get; set; }
        public string shelf_distribution { get; set; }
        public string shelf_prod_nr { get; set; }
        public string shelf_life { get; set; }
        public string charge { get; set; }
        public string shelf_description { get; set; }
        public string webtext { get; set; }
        public string daily_dosage { get; set; }
        public object ingredients { get; set; }
        public object composition { get; set; }
        public string factor { get; set; }
        public string risk_analysis { get; set; }
        public string conclusion { get; set; }
        public string color { get; set; }
        public string label { get; set; }
        public string purchase_price { get; set; }
        public double price { get; set; }
        public double sales_price { get; set; }
        public string tax_rate { get; set; }
        public string min_stock { get; set; }
        public string category { get; set; }
        public string fabrikant_id { get; set; }
        public bool archive { get; set; }
        public bool active { get; set; }
        public string price_original { get; set; }
        public string sales_price_original { get; set; }
        public int current_stock { get; set; }
        public bool stock_warning { get; set; }
        public ImageFront image_front { get; set; }
        public ImageThumb image_thumb { get; set; }
        public List<File> File { get; set; }
    }

    public class Products
    {
        public Product Product { get; set; }
    }

ProductViewModel.cs

public class ProductViewModel : BaseViewModel
    {
        private ObservableCollection<Products> products;

        public ProductViewModel()
        {
            ProductList = new ObservableCollection<Products>();
            GetProducts();
        }

        public ObservableCollection<Products> ProductList
        {
            get { return products; }
            set
            {
                products = value;
                OnPropertyChanged();
            }
        }

        public async void GetProducts()
        {
            ProductList.Clear();
            ProductList = await App.RestAPIManager.GetProductsAsync();
            
            Console.WriteLine("test products: " + ProductList.Count);

        }
}

ProductPage.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"
             x:Class="xxx_xxxxx.Views.ProductPage"
             xmlns:vm="clr-namespace:xxx_xxxxx.ViewModels" xmlns:model="clr-namespace:xxx_xxxxxx.xxxxxx">


    <ContentPage.BindingContext>
        <vm:ProductViewModel/>
    </ContentPage.BindingContext>
    <StackLayout>        
        <CollectionView x:Name="productList"
                ItemsSource="{Binding ProductList}"
                VerticalScrollBarVisibility="Never" 
                SelectionMode="Single"
                         BackgroundColor="LightGray">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Padding="10">
                        <Label Text="{Binding Product.name}" 
                            FontSize="Small"
                             TextColor="Blue"/>
                        <Label Text="{Binding Product.price}" 
                            FontSize="Small" />
                        <Button Text="hoi">
                            
                        </Button>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
</ContentPage>

【问题讨论】:

  • 你的投标表达式应该只是Text="{Binding name}"
  • 在数据上下文“产品”错误中找不到成员
  • 我在 ProductViewModel.cs 中将 ProductList 定义为 public ObservableCollection ProductList{}。重点是迭代产品并在集合视图中显示它们
  • 是的,它是一个 C# 属性
  • 是否显示“hoi”按钮?

标签: xamarin xamarin.forms


【解决方案1】:

绑定时尽量去掉Product的前缀。

    <CollectionView x:Name="productList"
            ItemsSource="{Binding ProductList}"
            VerticalScrollBarVisibility="Never" 
            SelectionMode="Single"
                     BackgroundColor="LightGray">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout Padding="10">
                    <Label Text="{Binding name}" 
                        FontSize="Small"
                         TextColor="Blue"/>
                    <Label Text="{Binding price}" 
                        FontSize="Small" />
                    <Button Text="hoi">
                        
                    </Button>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

注意:我们应该这样编码:

 <Label Text="{Binding name}" 
                        FontSize="Small"
                         TextColor="Blue"/>

而不是下面的代码:

 <Label Text="{Binding Product.name}" 
                        FontSize="Small"
                         TextColor="Blue"/>

【讨论】:

  • 如上所述,杰森“在数据上下文''产品'错误中找不到成员”。 itemssource 中有问题
  • 我的 Observablecollection 还是 Observablecollection
  • [0:] Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.ObjectModel.ObservableCollection1[xxx_xxxxx.Models.Category]' ` 这意味着您正在尝试获取 IEnumerable 但响应只有一个值。所以请尽量确保它是您回复中的数据列表。
  • 另外,你为什么要把单模式变成单模式,这很奇怪。公开class Products { public Product Product { get; set; } }
  • 如果问题仍然存在,您是否方便将基本演示发布到github或onedriver,以便我们进行测试?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 2023-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
相关资源
最近更新 更多