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

Posted

技术标签:

【中文标题】如何从 Blazor 服务器端应用程序中的 Razor 页面导航到 Blazor 组件?【英文标题】:How to navigate to a blazor component from a razor page in a Blazor server-side app? 【发布时间】:2021-05-10 01:15:16 【问题描述】:

我需要从 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");

但这也不起作用。

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

【问题讨论】:

作为第一次尝试,我将重定向到视图保存相应<component type="typeof(YourRootComponentType)" /> 的页面和方法。如果您需要将一些参数传递给您的组件,您可以在组件初始化后使用NavigationManager 从 URL 中读取部分内容。 请提供更多信息。 (非 Blazor)页面是否与 Blazor 应用程序位于同一站点(Web 应用程序)上?如果是这样,那么您的 startup.cs 是如何配置的。您为 Blazor SPA 使用的 URL。 【参考方案1】:

但是,我可能会遗漏一个步骤,我将创建一个单独的问题。这里的问题是如何从 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。您可以将其设置为“仪表板”,而不是来自 ChallengeAsync,而是来自您的 RedirectToLogin 组件 (RedirectToLogin.razor)。就是这样……

再一次,流程是 RedirectToLogin (Blazor) => Login.cshtml.cs (当前代码) => Auth server => Blazor(也许是“仪表板”)

当您到达“仪表板”时,如果您使用了我在第一个答案中提供的代码,则访问令牌应该存储在您的本地存储中。如果你问怎么做,那么答案是:这段代码很神奇:

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;
        

这一切都在我的第一个答案中。

【讨论】:

再次感谢您提供详细信息和 sn-ps。但是我无法掌握它。我有太多的组件和页面飞来飞去只是为了一个简单的重定向,我的问题应该很容易解决。我将提出一个新问题,说明我需要什么以及问题是什么。

以上是关于如何从 Blazor 服务器端应用程序中的 Razor 页面导航到 Blazor 组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 blazor(服务器端)Web 应用程序获取访问令牌?

如何将 Blazor 中的所有注册服务添加到 Simple Injector?

如何在服务器端 Blazor 中存储会话数据

如何在 blazor webassembly 项目中对服务器端控制器中的用户进行身份验证?

如何在 Blazor 服务器端模拟延迟?

如何向服务器端 Blazor 项目添加控制器(而非视图)支持