我正在尝试获取客户数据以将其解析为客户对象以显示在TableView上。以下代码有时会起作用,有时不起作用。每当它崩溃时,它会显示foreach循环中的客户数据为空,即使我每次都运行相同的代码。我不知道在这种情况下会出现什么问题。我在这个平台上很新。如果我遗漏了任何/额外信息,请告诉我。
namespace TableViewExample
{
public partial class MyDataServices : ContentPage
{
private ODataClient mODataClient;
private IEnumerable <IDictionary<string,object>> Customers;
public MyDataServices ()
{
InitializeComponent ();
InitializeDataService ();
GetDataFromOdataService ();
TableView tableView = new TableView{ };
var section = new TableSection ("Customer");
foreach (var customers in Customers) {
//System.Diagnostics.Debug.WriteLine ((string)customers ["ContactName"]);
var name = (string)customers ["ContactName"];
var cell = new TextCell{ Text = name };
section.Add (cell);
}
tableView.Root.Add (section);
Padding = new Thickness (10, 20, 10, 10);
Content = new StackLayout () {
Children = { tableView }
};
}
private void InitializeDataService(){
try {
mODataClient = new ODataClient ("myURL is here");
}
catch {
System.Diagnostics.Debug.WriteLine("ERROR!");
}
}
private void GetDataFromOdataService (){
try {
Customers = mODataClient.For ("Customers").FindEntries ();
}
catch {
System.Diagnostics.Debug.WriteLine("ERROR!");
}
}
}
}
答案 0 :(得分:1)
这里有很多帮助,但是有些事情需要考虑: -
听起来数据服务可能无法联系/离线;太忙或甚至可能自己抛出异常并返回您不希望收到的数据响应,然后在您的应用程序中触发异常并崩溃,因为您总是期望得到确切的响应,而不会遇到任何异常响应/事件。
如果您通过互联网联系外部服务,可能只是您的互联网连接速度慢/有故障而且没有足够快地返回信息。
在您的代码中,您假设您始终从服务器获得响应 - 并且此响应将始终是您期望解码的预期结构 - 而不会考虑数据服务返回的任何异常响应的可能性。我个人没有使用过 ODataClient ,所以不确定在没有数据接收/超时的情况下它是如何表现的,或者在你的情况下是数据服务,以及它在响应错误请求时的内部行为等
我假设会抛出异常,并且确实执行了调试行指示失败。
您可能还想调整此语句,以便您也写出例外: -
private void GetDataFromOdataService ()
{
try
{
Customers = mODataClient.For ("Customers").FindEntries ();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("ERROR!" + ex.ToString());
}
}
如果响应错误,那么Customers = .....
处的行将抛出异常,因为可能没有客户返回或者来自dataservice的响应中包含了一些其他信息。
Customers
变量也将 null 此时我假设由于此失败。
因此,当您回到foreach (var customers in Customers) {
处的代码时,它会抛出空引用异常,因为Customers
实际上是 null 。
由于所有当前代码都在构造函数中执行而没有任何try
和catch
块,所以此时它也会使应用程序崩溃。
此外,您正在构造函数中完成所有这些工作。尝试分离出来。我没有仔细调查构造函数在 iOS 页面生命周期中的调用位置,但是,如果它位于 viewDidLoad 中,那么你有10秒钟的时间要完成的一切,否则它会自动退出。我想在你的情况下,这不适用。
继续尝试将布局控件放在构造函数中,然后将数据任务移动到 OnAppearing 覆盖。
使用异步肯定也是可取的,但请记住,您需要检查数据服务的响应,因为错误也可能嵌入到响应中,您需要检测它何时是确定处理数据。