简体   繁体   中英

How to navigate to a blazor component from a razor page in a Blazor server-side app?

I need to navigate from a razor page to a blazor page, so I tried to do:

public class LoginCallbackModel : PageModel
{
    private readonly NavigationManager navigationManager;

    public LoginCallbackModel(
        NavigationManager navigationManager)
    {
        this.navigationManager = navigationManager;
    }

    public async void OnGet()
    {
        if (User.Identity.IsAuthenticated)
        {
            var accessToken = await HttpContext.GetTokenAsync("access_token");
            var idToken = await HttpContext.GetTokenAsync("id_token");
        }

        navigationManager.NavigateTo("Dashboard");
    }
}

But I get this exception:

RemoteNavigationManager' has not been initialized

I also tried:

RedirectToPage("Dashboard");

But this doesn't work either.

I need to use a razor page because I have access to the HttpContext. So how can I navigate to a component from the page?

However there's a step that I might be missing and I will create a separate question. The problem here is how to redirect from a razor page to a blazor page. I've tried different flavors of Redirect but none are working.

Yes, create a separate question. In the meanwhile, here's the answer:

Create a file named Login.cshtml.cs . This file should be called from Blazor (RedirectToLogin.razor).

This is the code of RedirectToLogin.razor

@inject NavigationManager NavigationManager

    @code{
    
        [Parameter]
        public string ReturnUrl { get; set; }
    
        protected override void OnInitialized()
        {
    
            NavigationManager.NavigateTo($"login?redirectUri={ReturnUrl}", forceLoad: true);
    
        }
    
    }

And this is the code of Login.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.IdentityModel.Tokens;


namespace <namespace of your app>.Pages
{
    public class LoginModel : PageModel
    {
       
        public async Task OnGet(string redirectUri)
        {
            await HttpContext.ChallengeAsync("oidc",
                   new AuthenticationProperties
                      {
                         RedirectUri = redirectUri,
                         IsPersistent = true,
                          ExpiresUtc = DateTimeOffset.UtcNow.AddHours(15)  
                                              // login expiration
                      });

        }
     
    }
}

The code above performs Authorization request to Auth server which return Authorization Code. RedirectUri will contain the url to redirect to when the Authorization request returns. You may set it to "Dashboard", not from ChallengeAsync but from your RedirectToLogin component (RedirectToLogin.razor). That is all...

Once again, the flow is RedirectToLogin (Blazor) => Login.cshtml.cs (cuurent code) => Auth server => Blazor( perhaps, "Dashboard")

By the time you arrive at the "Dashboard", the access token should be stored in your local storage if you've used the code I provided in the first answer. If you ask how then the answer is: this code do the magic:

var token = await HttpContext.GetTokenAsync("access_token");

This code instruct the http context to get the access token in exchange for the Authorization Code. When does it happen? When your Blazor is accessed 'for the first time'; that is to say, before it is created at all - this is the time when _Host.cshtml is fulfilling its role, which includes a Get operation (mind you it's http request that is handled by a Get method:

public async Task OnGetAsync()
        {
            var token = await HttpContext.GetTokenAsync("access_token");
            var idToken = await HttpContext.GetTokenAsync("id_token");
            AccessToken = token;
            IDToken  = idToken;
        }

It's all in my first answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM