Xamarin -shell navigatin无法使用服务

发布于 2025-01-29 10:46:05 字数 4607 浏览 4 评论 0原文

我有一个Xamarin表单项目,我想实现的目标是,当我获得401响应代码时,请转到我的loginPage,因为令牌将不再有效。

我有一个logout方法,其中我称之为gotoasync方法,但它返回错误,我不知道为什么。

错误:

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

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


        // 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;

        }

这是我的注销方法

 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");
                }

            }
        }

,这是我的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方法上继续使用代码,并且我不希望它

等待Shell.current.gotoasync($” ”);

有效的路由是“登录”,然后在loginPage构造函数之后给出空错误。

等待shell.current.gotoasync($“ login”);

所以当我在主页上时,我要实现的目标是登录页面。我已经能够远离ViewModels来实现这一目标,但是从我的AzureApiservice来看,它行不通。为什么会发生这种情况?请帮忙,谢谢。

编辑

在断点上,我已经看到它从此行

等待shell.current.gotoasync($“ login”);

loginpage 然后,构造函数再次到达该行,然后再次到达构造函数,当它第三次恢复到该行时,它将提供nullReferenceException。我不知道为什么会发生这种情况,

所以这是我使用路由//登录是正确的路由时会发生什么。它继续使用代码。

I have a Xamarin Forms project and what I want to achieve is when I get a 401 response code go to my LoginPage as the token will be no longer valid.

I have a Logout method in which I call the GoToAsync method but it returns an error and I don't know why.

Error:

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

I have a Service class called AzureApiService in which I have this generic get method. When the response is not successful I want it to go to the login page.


        // 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;

        }

This is my Logout method

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

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

This is what I have on my 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(
quot;//main");
                }

            }
        }

And here is my AppShell with my Shell routing

<!--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>

Here are the routes I have registered

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));
        }

If I use this route it will just do nothing and then continue with the code on my HttpGetAsync method and I don't want it to

await Shell.Current.GoToAsync($"//login");

The route that works it's "login" and then gives null error after LoginPage constructor.

await Shell.Current.GoToAsync($"login");

So what I want to achieve is going to the login page when I'm on the main page. I have been able to achieve that so far from the ViewModels but from my AzureApiService it doesn't work. Why is this happening? Please help and thanks.

EDIT

With a breakpoint I have seen that it goes from this line

await Shell.Current.GoToAsync($"login");

to the LoginPage constructor then to that line again and the constructor again and when it gets back the third time to that line it will give the NullReferenceException. I have no idea why this is happening

So here is what happens when I use the route //login which is the correct one. It goes on with the code.

Debugging video

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉世弥音 2025-02-05 10:46:05

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

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

Try run it from application main thread like

Device.BeginInvokeOnMainThread(async () => {
   await Shell.Current.GoToAsync(
quot;//{nameof(SomePage)}");
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文