【发布时间】:2020-09-05 16:01:10
【问题描述】:
我正在将 ASP.NET Core 后端中的类别作为数组加载到 Xamarin 应用程序中,用于 ListView 的分组项目,如https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/customizing-list-appearance#grouping。
09-06 23:25:36.679 W/SSLCertificateSocketFactory(29717): Bypassing SSL security checks at caller's request
[0:] Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'BoerPlaza.Models.Products.Category' 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. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path '[0].id', line 1, position 7.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x003a0] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x0006d] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList (System.Collections.IList list, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonArrayContract contract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id) [0x00173] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, System.Object existingValue, System.String id) [0x000dc] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x0007f] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00054] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x0002d] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <2073514815234917a5e8f91b0b239405>:0
at Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value) [0x00000] in <2073514815234917a5e8f91b0b239405>:0
at BoerPlaza.Services.CategoryDataStore.GetCategoriesParentAsync () [0x0013b] in C:\Users\QuanDar\source\repos\BoerPlaza\Frontend\BoerPlaza\BoerPlaza\Services\CategoryDataStore.cs:47
at BoerPlaza.ViewModels.BrowseCategoryViewModel.ExecuteLoadCategoriesCommand () [0x00068] in C:\Users\QuanDar\source\repos\BoerPlaza\Frontend\BoerPlaza\BoerPlaza\ViewModels\BrowseCategoryViewModel.cs:49
模型的问题是你必须从 ObservableCollection 继承。所有其他模型都工作正常,只是这个我因为继承而无法工作。当我删除继承时,一切正常,但我无法在 ListView 中对我的项目进行分组。
尝试使用 List 而不是 ObservableCollection。不要紧。 Xamarin 模型:(不包括 EF Core 模型,但 JSON 应该显示可用的内容)
public class Category : ObservableCollection<Category>
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Category Parent { get; set; }
public Image Image { get; set; }
public ObservableCollection<Category> Children => this;
public Category(string title)
{
this.Title = title;
}
public Category()
{
}
}
来自后端的 JSON:
[
{
"id": 1,
"title": "Vlees",
"description": null,
"parent": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": [
{
"id": 5,
"title": " Kip",
"description": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": []
},
{
"id": 6,
"title": "Koe",
"description": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": []
}
]
},
{
"id": 2,
"title": "Groente",
"description": null,
"parent": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": [
{
"id": 9,
"title": "Boemkool",
"description": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": []
}
]
},
{
"id": 3,
"title": "Fruit",
"description": null,
"parent": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": [
{
"id": 10,
"title": "Appel",
"description": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": []
},
{
"id": 11,
"title": "Peer",
"description": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": []
}
]
},
{
"id": 4,
"title": "Kruiden",
"description": null,
"parent": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": [
{
"id": 12,
"title": "Knoflook",
"description": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": []
},
{
"id": 13,
"title": "Peterselie",
"description": null,
"image": {
"alt": "Bedrijven WordPress themes",
"pathThumbnail": "Templates/constructie.jpg"
},
"children": []
}
]
}
]
HTTP 服务
public async Task<IEnumerable<Category>> GetCategoriesParentAsync()
{
if (IsConnected)
{
var json = await client.GetStringAsync($"api/products/categories/parent");
return await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<Category>>(json));
}
return this.categories;
}
视图模型: 当我自己设置数组时,一切正常。
public ObservableCollection<Category> Categories { get; set; }
...
public async Task ExecuteLoadCategoriesCommand()
{
IsBusy = true;
this.PreviousCategoryHolder.Add(this.Categories);
try
{
Categories.Clear();
// This does not work and throws the error
//var categories = await CategoryStore.GetCategoriesParentAsync();
//foreach (var category in categories)
//{
// Categories.Add(category);
//}
// when I do it like this, it works and displays the items.
this.Categories = new ObservableCollection<Category>
{
new Category("Vlees")
{
new Category("kip"),
new Category("kip file")
},
new Category("Groente")
{
new Category("Appel"),
new Category("Banaan")
}
};
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
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="BoerPlaza.Views.BrowsePage">
<!-- binding context is in code behind -->
<ContentPage.Content>
<ListView x:Name ="categoriesListView"
IsGroupingEnabled="true"
ItemTapped="Handle_ItemTapped"
CachingStrategy="RecycleElement"
>
<ListView.GroupHeaderTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}"/>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
谢谢!
【问题讨论】:
-
请使用 json2csharp.com 检查您的模型。首先,您的模型属性都不匹配您的 json 中使用的命名约定
-
正在努力实现这一目标:docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/…。但随后使其与 JSON 一起工作。 json2csharp.com 只是创建了许多模型,我不需要嵌套的 ViewList。
-
您可以根据需要修改模型以消除嵌套,但这不会改变您发布的代码不符合 json 中使用的命名约定的事实。
标签: c# xamarin xamarin.forms xamarin.android asp.net-core-webapi