我正在尝试从我的Web API获取数据并将其显示在我的ListView上。 当我单击按钮检索数据时,它返回我并且错误:
[0:] Binding: MobileUI.Models.RootObject can not be converted to type 'System.Collections.IEnumerable'
所以我在Deserilization上创建了断点,它正确地返回了数据,但它没有显示在ListView上。
这是我的代码: -
ApiServices类中的GetUserAsync
public async Task<RootObject> GetUserAsync(string accessToken)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var json = await client.GetStringAsync("http://weburl/testrun/api/services/app/user/GetRoles");
var users = JsonConvert.DeserializeObject<RootObject>(json);
return users;
}
UserViewModel
private readonly ApiServices _apiServices = new ApiServices();
private RootObject _users;
public RootObject Users
{
get { return _users; }
set
{
_users = value;
OnPropertyChanged();
}
}
public ICommand GetUsersCommand
{
get
{
return new Command(async () =>
{
var accessToken = Settings.AccessToken;
Users = await _apiServices.GetUserAsync(accessToken);
});
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
JSON回复
{
"result": {
"items": [
{
"name": "Admin",
"displayName": "Admin",
"description": null,
"isStatic": true,
"permissions": [
"Pages.Users",
"Pages.Roles",
"Pages.Tenants"
],
"id": 1
},
{
"name": "Tenants",
"displayName": "Tenants",
"description": "",
"isStatic": false,
"permissions": [
"Pages.Tenants",
"Pages.Users"
],
"id": 12
},
{
"name": "Landlord",
"displayName": "Landlord",
"description": "",
"isStatic": false,
"permissions": [
"Pages.Tenants",
"Pages.Property",
"Pages.Payment",
"Pages.Feedback",
"Pages.Document",
"Pages.LandLord",
"Pages.Users"
],
"id": 14
},
{
"name": "User",
"displayName": "Users",
"description": "",
"isStatic": false,
"permissions": [
"Pages.Property",
"Pages.Payment",
"Pages.Feedback",
"Pages.Document"
],
"id": 20
}
]
},
"targetUrl": null,
"success": true,
"error": null,
"unAuthorizedRequest": false,
"__abp": true
}
XAML代码
<Button Command="{Binding GetUsersCommand}"
Text="Get All User Roles"
TextColor="White"
FontSize="20"
BackgroundColor="DodgerBlue"/>
<ListView ItemsSource="{Binding Users}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="0,10">
<Label Text="{Binding result}" />
<Label Text="{Binding success}" />
<Label Text="{Binding error}" />
<Label Text="{Binding displayName}" />
<Label Text="{Binding isStatic}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
注意:如果我将其转换为List,则会出现以下错误
未处理的例外:
Newtonsoft.Json.JsonSerializationException:无法反序列化 当前的JSON对象(例如{“name”:“value”})到类型中 'System.Collections.Generic.List`1 [MobileUI.Models.RootObject]' 因为该类型需要一个JSON数组(例如[1,2,3])来反序列化 正确。要修复此错误,请将JSON更改为JSON数组 (例如[1,2,3])或更改反序列化类型以使其正常 .NET类型(例如,不是整数的基本类型,不是集合 类似于数组或List的类型,可以从JSON反序列化 宾语。 JsonObjectAttribute也可以添加到类型中以强制它 从JSON对象反序列化。路径'结果',第1行,第10位。
编辑1:添加转换后的JSON响应
public class Item
{
public string name { get; set; }
public string displayName { get; set; }
public string description { get; set; }
public bool isStatic { get; set; }
public List<string> permissions { get; set; }
public int id { get; set; }
}
public class Result
{
public List<Item> items { get; set; }
}
public class RootObject
{
public Result result { get; set; }
public object targetUrl { get; set; }
public bool success { get; set; }
public object error { get; set; }
public bool unAuthorizedRequest { get; set; }
public bool __abp { get; set; }
}
答案 0 :(得分:2)
用此
替换您的UserViewModelprivate readonly ApiServices _apiServices = new ApiServices();
private ObservableCollection<Item> _users;
public ObservableCollection<Item> Users
{
get { return _users; }
set
{
_users = value;
OnPropertyChanged();
}
}
public ICommand GetUsersCommand
{
get
{
return new Command(async () =>
{
var accessToken = Settings.AccessToken;
var user_result = await _apiServices.GetUserAsync(accessToken);
if(user_result!=null)
{
Users =new ObservableCollection<Item>(user_result.result.items);
}
});
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}