【发布时间】:2021-10-11 11:28:42
【问题描述】:
我的应用程序中发生了一个非常奇怪的错误。
我有一个非常简单的辅助方法,用于在用户设备上存储一些很酷的数据:
public static async Task TrySetAsync(string key, string value)
{
try
{
await SecureStorage.SetAsync(key, value);
}
catch (Exception ex)
{
await App.Current.MainPage.DisplayAlert(
"Device incompatible",
"Your device is not compatible with this app.",
"Ok");
}
}
它工作得很好,从来没有出现过问题,但我决定在应用启动时执行兼容性检查,以便用户立即知道他们的设备不会切断它。为此,我决定在初始登录页面的 OnAppearing() 方法中实现它。它看起来像这样:
protected override async void OnAppearing()
{
try
{
// Try to save data to a random container
string tempKey = System.Guid.NewGuid().ToString();
// Should throw an exception if SecureStorage is not compatible
await Xamarin.Essentials.SecureStorage
.SetAsync(tempKey, string.Empty);
// Remove the datum
Xamarin.Essentials.SecureStorage
.Remove(tempKey);
}
catch
{
await App.Current.MainPage.DisplayAlert(
"Device incompatible",
"This device does not support secure storage required for the application.",
"Ok");
App.Terminate();
}
base.OnAppearing();
}
我从项目中删除了权利来测试我的小混合物,但它毫无问题地通过了它。不会抛出异常。但是在登录时,使用原始 TrySetAsync 方法(第一个代码 sn-p)时,会引发预期的异常(缺少权利)。调试器进入 try 块并没有问题地离开它。
总结:
看起来,当在 OnAppearing() 中引用 SecureStorage 时,该应用不需要任何权利,但在主 App 类中定义的 TrySetAsync(...) 中引发了预期的异常。
有什么建议吗?
附:最初我在 OnAppearing() 中将 GetAsync 与随机 guid 字符串一起使用,我将其更改为 SetAsync 和 Remove,认为可能获取数据不需要兼容性。 总的来说,我从来没有遇到过 SecureStorage 这样的问题,而且这对我来说确实像是一些内部错误。\
回答
我不喜欢使用 string.Empty 作为值。看来 SecureStorage.SetAsync 将忽略此类值并且不存储它,这样就不会引发任何异常。此外,尝试从 SecureStorage 获取不存在的密钥也不会导致缺少授权异常
【问题讨论】:
-
极不可能(我想说不可能)代码的位置允许使用不存在的权利。您观察到的症状很可能并不意味着权利有效。我不知道为什么没有抛出异常,但我会更彻底地测试。一个彻底的测试是将一个值存储到安全存储中,然后将其读回另一个变量中。使用 debug writelines 查看是否所有这些代码行都被执行,并查看从存储返回的值是否正确。
-
预测:如果您在第一次调用securestorage 后有调试写入行,则该行将永远不会被执行。该 try 块中的任何以下行也不会。如果这个预测被证明是正确的,那么我们将调查这意味着什么。还要添加一个调试写入行作为
catch的第一行。如果DisplayAlert在OnAppearing内部完成时失败,我不会感到惊讶。 -
另外,您是否检查过 VS 输出窗格,看看在执行此代码时是否有任何警告或错误消息?
-
嗨史蒂夫,很抱歉回复太长了,我今天只能坐下来。按照你的建议,我写了一个更完整的测试,我发现有两种情况没有抛出异常: 1. SetAsync 中的值是 string.Empty 或 null:app 忽略该值并且不存储它,没有异常被抛出。 2. GetAsync 引用的键目前在设备 KeyChain 上不存在:fetch 返回 null(如预期)并且不抛出异常。除了这两种情况,代码按预期工作。我很不幸(而且有点愚蠢)使用 string.Empty 而不是同时调用 Get 和 Set
-
我将编辑我的原始问题以包含答案并将其作为问题报告给他们的 GitHub。感谢您的帮助
标签: xamarin xamarin.forms xamarin.ios xamarin.essentials