我一直在关注Azure移动应用程序和简易表格(https://blog.xamarin.com/getting-started-azure-mobile-apps-easy-tables/)的教程。一切都进行得很顺利,我设法到了测试我的应用程序的点,似乎没有返回任何数据,我不知道为什么,我也没有收到任何错误正在使这个问题的追踪更加困难。
好的开始我拥有我的Azure数据库(配置为允许访问Azure服务)并且我创建了我的表并使用EasyTables工作。我使用Postman(https://www.getpostman.com/)应用程序来测试我的API并确保使用https://myproject.azurewebsites.net/tables/users
从我的数据库返回数据,该数据以json的形式返回我的数据。
我的数据库表名为users
,其结构非常基础(用于测试),包含两列id
和FirstName
。我已经用虚拟数据填充了我的表格,我已经证明可以使用Postman从我的azure uri返回。
这是开始运行的基础工作,这是我的项目层次结构的快照。
MyProject的/型号/ users.cs
这是实体数据,其名称与数据库中的表匹配。
using System;
using Microsoft.WindowsAzure.MobileServices;
using Newtonsoft.Json;
namespace MyProject
{
public class users
{
[JsonProperty(PropertyName = "Id")]
public string id { get; set; }
public string FirstName {get; set; }
}
}
MyProject的/服务/ AzureService.cs
至关重要的是,我们在此处执行public async Task<IEnumerable<users>> GetUsers()
任务,并触发Inialization任务(这是定义应用网址的位置)。
using System;
using Microsoft.WindowsAzure.MobileServices;
using Microsoft.WindowsAzure.MobileServices.Sync;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.WindowsAzure.MobileServices.SQLiteStore;
using System.Diagnostics;
using Xamarin.Forms;
using MyProject;
using System.IO;
using Plugin.Connectivity;
[assembly: Dependency(typeof(AzureService))]
namespace MyProject
{
public class AzureService
{
public MobileServiceClient Client { get; set; } = null;
IMobileServiceSyncTable<users> userTable;
public async Task Initialize()
{
if (Client?.SyncContext?.IsInitialized ?? false)
return;
var appUrl = "https://myproject.azurewebsites.net";
//Create our client
Client = new MobileServiceClient(appUrl);
//InitialzeDatabase for path
var path = "syncstore.db";
//path = Path.Combine(MobileServiceClient.DefaultDatabasePath, path);
//setup our local sqlite store and intialize our table
var store = new MobileServiceSQLiteStore(path);
//Define table
store.DefineTable<users>();
//Initialize SyncContext
await Client.SyncContext.InitializeAsync(store);
//Get our sync table that will call out to azure
userTable = Client.GetSyncTable<users>();
}
public async Task SyncUsers()
{
try
{
await userTable.PullAsync("allUsers", userTable.CreateQuery());
await Client.SyncContext.PushAsync();
}
catch (Exception ex)
{
Debug.WriteLine("Unable to sync users, that is alright as we have offline capabilities: " + ex);
}
}
//
//Get Users
public async Task<IEnumerable<users>> GetUsers()
{
await Initialize();
await SyncUsers();
return await userTable.ToEnumerableAsync(); ;
}
}
}
MyProject的/视图/ UserList.xaml
为了测试的目的,我保持简短和简约。一个简单的列表,它的源设置为UsersList(它是ViewModel中的Observable集合)。列表中的每个项目都绑定到FirstName
。
<?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:MyProject;assembly=MyProject"
x:Class="MyProject.UserList"
Title="UserList">
<ListView x:Name="userList"
ItemsSource="{Binding UsersList}"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
RefreshCommand="{Binding LoadUsersCommand}"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HorizontalOptions="StartAndExpand" Orientation="Horizontal" Padding="15,5,0,0">
<StackLayout Padding="5,0,0,0" VerticalOptions="StartAndExpand" Orientation="Vertical">
<Label Text="{Binding FirstName}" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
MyProject的/视图/ UserList.xaml.cs
这只是说明UserList绑定到viewmodel,当列表出现时会从viewmodel中触发load users命令。
using System;
using System.Collections.Generic;
using Plugin.Connectivity;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace MyProject
{
public partial class UserList : ContentPage
{
UsersViewModel vm;
public UserList()
{
InitializeComponent();
BindingContext = vm = new UsersViewModel();
}
protected override async void OnAppearing()
{
base.OnAppearing();
vm.LoadUsersCommand.Execute(null);
}
}
}
MyProject的/视图模型/ UsersViewModel.cs
此文件功能最多,视图模型具有可观察的定义和加载用户命令。
using System;
using MvvmHelpers;
using System.Windows.Input;
using System.Threading.Tasks;
using System.Diagnostics;
using Xamarin.Forms;
using System.Linq;
using Microsoft.WindowsAzure.MobileServices;
namespace MyProject
{
public class UsersViewModel : BaseViewModel
{
AzureService azureService;
public UsersViewModel()
{
azureService = DependencyService.Get<AzureService>();
}
public ObservableRangeCollection<users> UserList { get; } = new ObservableRangeCollection<users>();
string loadingMessage;
public string LoadingMessage
{
get { return loadingMessage; }
set { SetProperty(ref loadingMessage, value); }
}
ICommand loadUsersCommand;
public ICommand LoadUsersCommand =>
loadUsersCommand ?? (loadUsersCommand = new Command(async () => await ExecuteLoadUsersCommandAsync()));
async Task ExecuteLoadUsersCommandAsync()
{
try
{
LoadingMessage = "Loading Users...";
IsBusy = true;
var users = await azureService.GetUsers();
UserList.ReplaceRange(users);
}
catch (Exception ex)
{
Debug.WriteLine("OH NO!" + ex);
await Application.Current.MainPage.DisplayAlert("Sync Error", "Unable to sync users, you may be offline", "OK");
}
finally
{
IsBusy = false;
}
}
}
}
我在运行应用程序时突然出现了几个断点,看看我是否可以找到问题的根源,缺少错误意味着我没有参考框架可供使用。
事件触发的当前顺序如下(基于我输入的断点):
public ObservableRangeCollection<users> UserList { get; } = new ObservableRangeCollection<users>();
- UserViewModel azureService = DependencyService.Get<AzureService>();
- UserViewModel var users = await azureService.GetUsers();
- UserViewModel await Initialize();
- AzureService public async Task Initialize()
- AzureService await SyncUsers();
- AzureServce public async Task SyncUsers()
- AzureService return await userTable.ToEnumerableAsync(); ;
- AzureService UserList.ReplaceRange(users);
- UserViewModel 然后使用模拟器将列表加载到我的MacBook Pro上,但它是空的,根本没有数据。任何人都可以帮助我理解为什么我无法获取我的数据?他们的断点是否应该到位并检查某些物品是否存在?
就像我说没有实际错误这是一个艰难的错误,但它也可能是非常简单的,任何帮助都是值得赞赏的。
更新
在我的初步调查之后,我已在我的代码中添加了if
语句,特别是在OnAppearing
中的UserList.xaml.cs
方法中。我在UserList
中添加UserViewModel.cs
集合的代码检查的代码是否为0。
protected override async void OnAppearing()
{
base.OnAppearing();
if (vm.UserList.Count == 0)
vm.LoadUsersCommand.Execute(null);
else
{
...
}
vm.LoadUsersCommand.Execute(null);
}
有趣的是,UserList
总是以0返回。所以问题看起来就像UsersViewModel.cs
public ObservableRangeCollection<users> UserList { get; } = new ObservableRangeCollection<users>();
导致这种情况的原因是什么?
答案 0 :(得分:0)
我唯一能看到的是你将id列重命名为Id - 在客户端上,它需要是id(小写)。
还有其他一些错误,但应该很容易找到调试器。我看到其中一个已被指出。