Xamarin - shell 导航无法从服务模式运行

nvbavucw  于 2023-03-10  发布在  Shell
关注(0)|答案(1)|浏览(121)

我有一个Xamarin Forms项目,我想要实现的是当我得到一个401响应代码时,转到我的LoginPage,因为令牌将不再有效。
我有一个Logout方法,我在其中调用了GoToAsync方法,但它返回了一个错误,我不知道为什么。
错误:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

我有一个名为AzureApiService的Service类,其中有这个通用get方法,当响应不成功时,我希望它转到登录页面。

// Generic Get Method
        public async Task<T> HttpGetAsync<T>(string url, string token)
        {
            T result = default(T);

            try
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                HttpResponseMessage response = httpClient.GetAsync(url).Result;
                HttpContent content = response.Content;

                if (response.IsSuccessStatusCode)
                {
                    var jsonResponse = await content.ReadAsStringAsync();
                    result = JsonConvert.DeserializeObject<T>(jsonResponse);
                }
                else
                {
                    await Logout();
                    //throw new Exception(((int)response.StatusCode).ToString() + " - " + response.ReasonPhrase);
                }
            }
            catch (Exception ex)
            {
                OnError(ex.ToString());
            }

            return result;

        }

这是我的Logout方法

private async Task Logout()
        {
            await Shell.Current.GoToAsync($"login");

            //if (!CurrentPropertiesService.GetCart().Equals(""))
            //{
            //    CurrentPropertiesService.RemoveCart();
            //}
            //CurrentPropertiesService.Logout();
        }

这是我的LoginPage上的内容

[XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LoginPage : ContentPage
    {
        private static string token;
        private AzureApiService _azureApiService;

        public LoginPage()
        {
            _azureApiService = new AzureApiService();
            InitializeComponent();
            go();

        }

        protected override async void OnAppearing()
        {
            base.OnAppearing();

            !_azureApiService.IsExpired(CurrentPropertiesService.GetToken())
            if (CurrentPropertiesService.IsAuth())
            {
                var hola = CurrentPropertiesService.GetToken();
                if (!_azureApiService.IsExpired(hola))
                {
                    await Shell.Current.GoToAsync($"//main");
                }

            }
        }

这是带有Shell路由的AppShell

<!--As it calls before TabBar it will skip over displaying anything else-->
    <ShellItem Route="login">
        <ShellContent ContentTemplate="{DataTemplate local:LoginPage}"/>
    </ShellItem>

    <TabBar Route="main">
        <Tab Title="Explorar" Icon="tab_feed.png">
            <ShellContent  ContentTemplate="{DataTemplate local:CategoryPage}" />
        </Tab>
        <Tab Route="CartPage" Title="Carrito" Icon="tab_feed.png">
            <ShellContent  ContentTemplate="{DataTemplate local:CartPage}" />
        </Tab>
        <Tab Route="InvoicePage" Title="Factura" Icon="tab_feed.png">
            <ShellContent  ContentTemplate="{DataTemplate local:InvoicePage}" />
        </Tab>
    </TabBar>

这是我登记的路线

public AppShell()
        {
            InitializeComponent();

            Routing.RegisterRoute("login", typeof(LoginPage));
            Routing.RegisterRoute(nameof(CategoryPage), typeof(CategoryPage));
            Routing.RegisterRoute(nameof(CartPage), typeof(CartPage));
            Routing.RegisterRoute("InvoicePage", typeof(InvoicePage));
        }

如果我使用这种方法,它将什么也不做,然后继续我的HttpGetAsync方法上的代码,我不希望它这样
await Shell.Current.GoToAsync($"//login");
工作的路由是“登录”,然后在LoginPage构造函数后给出null错误。
await Shell.Current.GoToAsync($"login");
所以我想实现的是当我在主页面时进入登录页面。我已经能够从ViewModels实现这一点,但从我的AzureApiService它不工作。为什么会发生这种情况?请帮助和感谢。

编辑

使用断点时,我看到它从此行开始
x1米11米1x
LoginPage构造函数,然后再到那一行,再到构造函数,当它第三次回到那一行时,它会给予NullReferenceException,我不知道为什么会这样
这是当我使用route //login时发生的事情,这是正确的,它继续运行代码。
Debugging video

z0qdvdin

z0qdvdin1#

尝试从应用程序主线程运行它

Device.BeginInvokeOnMainThread(async () => {
   await Shell.Current.GoToAsync($"//{nameof(SomePage)}");
});

相关问题