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

时间:2021-02-05 17:13:12

标签: asp.net-core blazor blazor-server-side

我需要从一个 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。那么如何从页面导航到组件?

1 个答案:

答案 0 :(得分: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
                      });

        }
     
    }
}

上面的代码向Auth服务器执行授权请求,返回授权码。 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;
        }

这都是我的第一个答案。