如何在 Blazor 服务器端应用程序中从 Razor 页面导航到 Blazor 组件?

3

我需要从 Razor 页面导航到 Blazor 页面,因此我尝试执行以下操作:

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

但我遇到了这个异常:

'RemoteNavigationManager'尚未初始化

我也尝试过:

RedirectToPage("Dashboard");

但这也不起作用。

我需要使用 Razor 页面,因为我可以访问 HttpContext。那么我该如何从页面导航到组件?


作为第一次尝试,我会将页面和方法重定向到视图持有相应的<component type="typeof(YourRootComponentType)" />的位置。如果您需要向组件传递一些参数,您可以使用NavigationManager在组件初始化后从URL中读取部分内容。 - Just the benno
请提供更多信息。非Blazor页面是否与Blazor应用程序位于同一网站(Web应用程序)上?如果是的话,您的startup.cs如何配置?您在Blazor SPA中使用的URL是什么? - MrC aka Shaun Curtis
1个回答

0
然而,我可能漏掉了一步,我将创建一个单独的问题。这里的问题是如何从Razor页面重定向到Blazor页面。我尝试了不同的重定向方式,但都没有起作用。
是的,请创建一个单独的问题。与此同时,这是答案:
创建一个名为Login.cshtml.cs的文件。这个文件应该从Blazor中调用(RedirectToLogin.razor)。
以下是RedirectToLogin.razor的代码:
@inject NavigationManager NavigationManager

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

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

        }
     
    }
}

上面的代码执行了向授权服务器发出授权请求,并返回授权码。RedirectUri将包含在授权请求返回时要重定向到的URL。您可以将其设置为“Dashboard”,但不是从ChallengeAsync,而是从您的RedirectToLogin组件(RedirectToLogin.razor)中设置。就是这样...

再次强调,流程是 RedirectToLogin(Blazor)=> Login.cshtml.cs(当前代码)=> 授权服务器 => Blazor(可能是“Dashboard”)

当您到达“Dashboard”时,如果您使用我在第一个答案中提供的代码,访问令牌应该已存储在您的本地存储中。如果您想知道如何实现的,答案是:这段代码会帮您实现魔法:

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

这段代码指示http上下文根据授权码获取访问令牌。它是在什么时候发生的呢?当你的Blazor首次被访问时;也就是说,在它被创建之前 - 这是_Host.cshtml履行其职责的时候,其中包括一个Get操作(请注意,这是由Get方法处理的http请求):

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

这都在我的第一个答案里。


再次感谢您提供详细的信息和片段。然而,我还是无法理解。我有太多的组件和页面在那里飞来飞去,只是为了一个简单的重定向,而我的问题应该很容易解决。我将提出一个新问题,说明我需要什么以及问题所在。 - Ivan-Mark Debono

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接