简体   繁体   English

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

[英]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:我需要从 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");
    }
}

But I get this exception:但我得到了这个例外:

RemoteNavigationManager' has not been initialized RemoteNavigationManager' 尚未初始化

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.我需要使用 razor 页面,因为我可以访问 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.这里的问题是如何从 razor 页面重定向到 blazor 页面。 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 .创建一个名为Login.cshtml.cs的文件。 This file should be called from Blazor (RedirectToLogin.razor).应该从 Blazor (RedirectToLogin.razor) 调用此文件。

This is the code of 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);
    
        }
    
    }

And this is the code of Login.cshtml.cs这是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. RedirectUri 将包含 url 以在授权请求返回时重定向到。 You may set it to "Dashboard", not from ChallengeAsync but from your RedirectToLogin component (RedirectToLogin.razor).您可以将其设置为“仪表板”,而不是来自 ChallengeAsync,而是来自您的 RedirectToLogin 组件 (RedirectToLogin.razor)。 That is all...就这些...

Once again, the flow is RedirectToLogin (Blazor) => Login.cshtml.cs (cuurent code) => Auth server => Blazor( perhaps, "Dashboard")再一次,流程是 RedirectToLogin (Blazor) => Login.cshtml.cs (当前代码) => Auth server => Blazor(也许,“仪表板”)

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.此代码指示 http 上下文获取访问令牌以换取授权代码。 When does it happen?什么时候发生? When your Blazor is accessed 'for the first time';当您的 Blazor 被“第一次”访问时; 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:也就是说,在它被完全创建之前 - 这是 _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;
        }

It's all in my first answer.这一切都在我的第一个答案中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将参数传递给服务器端 Blazor 中的 razor 组件? - How to pass a parameter to razor component in server-side Blazor? 如何在 Blazor 服务器应用程序中导航到文件夹的默认页面 (.razor)? - How to navigate to a folder's default page (.razor) in Blazor Server app? onclick 方法在 Blazor 服务器端 razor 组件中不起作用 - onclick method not working in Blazor server-side razor component 如何使用区域在剃刀组件库中使用 blazor 服务器端? - How do I use blazor server-side inside a razor component library using areas? 如何将 model 传输到 Blazor 服务器端的 Razor 组件? - How can I transfer a model to a Razor Component in Blazor server-side? 在 Blazor 服务器端如何检测用户是否试图离开当前页面 - In Blazor Server-Side how can I detect if the user tries to navigate off of the current page 无法在 Blazor razor 页面(Blazor 服务器端)中注入 Controller、DbContext - Cannot inject Controller, DbContext inside Blazor razor page (Blazor server-side) 如何访问 Blazor 服务器端的父组件? - How can I access the parent Component in Blazor server-side? 如何将记录添加到Blazor服务器端组件? - How to add logging to Blazor Server-side component? 如何从 MVC 迁移到 Blazor 服务器端? - How to migrate from MVC to Blazor Server-side?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM