为什么我的 Azure 移动应用程序没有返回任何数据?
Why is my Azure mobile app not returning any data?
我一直在关注有关 Azure 移动应用程序的简易表格的教程 (https://blog.xamarin.com/getting-started-azure-mobile-apps-easy-tables/)。一切进展顺利,我设法开始测试我的应用程序,它似乎没有 return 任何数据,我不知道为什么,我也没有收到任何错误这个问题的追踪比较困难。
好的,首先我有我的 Azure 数据库(配置为允许访问 Azure 服务),我已经创建了 table 并使用 EasyTables 工作。我使用 Postman (https://www.getpostman.com/) 应用程序来测试我的 API 并确保数据是使用 https://myproject.azurewebsites.net/tables/users
从我的数据库中 return 编辑的,return 编辑了我的数据json.
我的数据库 table 称为 users
,它的结构非常基本(用于测试),有两列 id
和 FirstName
。我已经用虚拟数据填充了我的 table,我已经证明可以使用 Postman 从我的 azure uri returned。
这是获得 运行ning 的基础工作,这是我的项目层次结构的快照。
MyProject/Model/users.cs
这是命名为与数据库中的 table 匹配的实体数据。
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/Services/AzureService.cs
至关重要的是,我们这里有 public async Task<IEnumerable<users>> GetUsers()
任务,它会触发初始化任务(这是定义应用程序 url 的地方)。
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/View/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/View/UserList.xaml.cs
这只是说明 UserList 绑定到视图模型,当列表出现时会从视图模型中触发加载用户命令。
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/ViewModel/UsersViewModel.cs
这个文件做的最多,视图模型定义了 observable 和 Load Users 命令。
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();
- Azure服务
public async Task SyncUsers()
- AzureService
return await userTable.ToEnumerableAsync(); ;
- AzureService
UserList.ReplaceRange(users);
- UserViewModel
然后使用模拟器将该列表加载到我的 MacBook pro 上,但它是空的,根本没有数据。任何人都可以帮助我理解为什么我无法获取我的数据吗?我应该设置它们的断点并检查某些项目是否存在吗?
就像我说的那样,没有实际错误,这是一个艰难的过程,但它也可能非常简单,我们将不胜感激。
更新
根据我的初步调查,我在我的代码中添加了一个 if
语句,特别是在 UserList.xaml.cs
中的 OnAppearing
方法中。我在 UserViewModel.cs
中添加的代码检查 UserList
集合是否为 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>();
可能是什么原因造成的?
我唯一能看到的是您将 id 列重命名为 Id - 在客户端上,它需要是 id(小写)。
其中还有一些其他错误,但使用调试器应该很容易找到它们。我看到其中一个已经被指出了。
我一直在关注有关 Azure 移动应用程序的简易表格的教程 (https://blog.xamarin.com/getting-started-azure-mobile-apps-easy-tables/)。一切进展顺利,我设法开始测试我的应用程序,它似乎没有 return 任何数据,我不知道为什么,我也没有收到任何错误这个问题的追踪比较困难。
好的,首先我有我的 Azure 数据库(配置为允许访问 Azure 服务),我已经创建了 table 并使用 EasyTables 工作。我使用 Postman (https://www.getpostman.com/) 应用程序来测试我的 API 并确保数据是使用 https://myproject.azurewebsites.net/tables/users
从我的数据库中 return 编辑的,return 编辑了我的数据json.
我的数据库 table 称为 users
,它的结构非常基本(用于测试),有两列 id
和 FirstName
。我已经用虚拟数据填充了我的 table,我已经证明可以使用 Postman 从我的 azure uri returned。
这是获得 运行ning 的基础工作,这是我的项目层次结构的快照。
MyProject/Model/users.cs
这是命名为与数据库中的 table 匹配的实体数据。
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/Services/AzureService.cs
至关重要的是,我们这里有 public async Task<IEnumerable<users>> GetUsers()
任务,它会触发初始化任务(这是定义应用程序 url 的地方)。
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/View/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/View/UserList.xaml.cs
这只是说明 UserList 绑定到视图模型,当列表出现时会从视图模型中触发加载用户命令。
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/ViewModel/UsersViewModel.cs
这个文件做的最多,视图模型定义了 observable 和 Load Users 命令。
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>();
- UserViewModelazureService = DependencyService.Get<AzureService>();
- UserViewModelvar users = await azureService.GetUsers();
- UserViewModelawait Initialize();
- AzureServicepublic async Task Initialize()
- AzureServiceawait SyncUsers();
- Azure服务public async Task SyncUsers()
- AzureServicereturn await userTable.ToEnumerableAsync(); ;
- AzureServiceUserList.ReplaceRange(users);
- UserViewModel
然后使用模拟器将该列表加载到我的 MacBook pro 上,但它是空的,根本没有数据。任何人都可以帮助我理解为什么我无法获取我的数据吗?我应该设置它们的断点并检查某些项目是否存在吗?
就像我说的那样,没有实际错误,这是一个艰难的过程,但它也可能非常简单,我们将不胜感激。
更新
根据我的初步调查,我在我的代码中添加了一个 if
语句,特别是在 UserList.xaml.cs
中的 OnAppearing
方法中。我在 UserViewModel.cs
中添加的代码检查 UserList
集合是否为 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>();
可能是什么原因造成的?
我唯一能看到的是您将 id 列重命名为 Id - 在客户端上,它需要是 id(小写)。
其中还有一些其他错误,但使用调试器应该很容易找到它们。我看到其中一个已经被指出了。