ASP.NET Core Blazor:从Razor组件导航到Razor页面

4

我试图从 Razor 组件重定向到 Razor 页面。如果用户未经授权,我希望从当前 Razor 组件重定向到登录 Razor 页面。

我已经重定向到登录组件。

public class RedirectToLogin : ComponentBase
    {
        [Inject]
        protected NavigationManager NavigationManager { get; set; }

        protected override void OnInitialized()
        {
            NavigationManager.NavigateTo("./Identity/Account/Login",true);
        }
    }

这一行代码出现了错误:NavigationManager.NavigateTo("./Identity/Account/Login");

Microsoft.AspNetCore.Components.NavigationException: '发生了类型为'Microsoft.AspNetCore.Components.NavigationException'的异常.'

我推测问题是从Razor组件到Razor页面的路由。


我遇到了同样的异常。你是如何解决这个错误的? - cickness
@cickness发布了我们接受的解决方案的答案。 - ChampChris
3个回答

1
如果有人正在寻找完整的解决方案,这是我的做法。
解决方案
步骤1: 在任何你想要的地方创建一个名为 RedirectToLogin.razor 的 Razor 组件。
例如:我将其创建在 Areas/Identity/Components 内。 然后将以下代码添加到此文件中:
@inject NavigationManager Navigation
@code {
    [Parameter]
    public string ReturnUrl { get; set; }

    protected override async Task OnInitializedAsync()
    {
            ReturnUrl = "~/" + ReturnUrl;
            Navigation.NavigateTo("Identity/Account/Login?returnUrl=" + ReturnUrl, true);
            await base.OnInitializedAsync();
    }
}

步骤二:<NotAuthorized></NotAuthorized> 标签内从 App.razor 使用此组件:

@inject NavigationManager Navigation
@using HMT.Web.Server.Areas.Identity.Components

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    @if (!context.User.Identity.IsAuthenticated)
                    {
                        <RedirectToLogin ReturnUrl="@Navigation.ToBaseRelativePath(Navigation.Uri)" />
                    }
                    else
                    {
                        <p role="alert">Sorry, you're not authorized to view this page.</p>
                    }
                </NotAuthorized>
            </AuthorizeRouteView>
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

完整的源代码

https://github.com/affableashish/blazor-server-auth/tree/feature/LayoutWithIdentityPages

演示

启动应用程序并尝试从浏览器访问授权视图(这里以Counter页面为例):

您将被重定向到登录页面:

您将成功登录并进入计数器页面:


当我的重定向返回时,我的URL是:https://localhost:5001/~/workflows 它包含 ~/,这是有原因的吗? - Victorio Berra

1

我使用下面的路由器(Router)时,遇到了一个重定向到未授权页面的问题。

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView  RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
            <NotAuthorized>
                <div class="container">
            <h1>Sorry</h1>
            <p>You're not authorized to reach this page.</p>
            <p>You may need to log in as a different user.</p>
            <a href="Identity/Account/Login">Log in</a>
        </div>
                @*<RedirectToLogin />*@
            </NotAuthorized>
            <Authorizing>
                <div class="container">
                    <h1>Authentication in progress</h1>
                    <p>Leave your hands on the keyboard,  scanning your fingerprints.  Ain't technology grand.</p>
                </div>
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
    <NotFound>
        <CascadingAuthenticationState>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </CascadingAuthenticationState>
    </NotFound>
</Router>

这暂时足够应用程序使用了。

抱歉打扰,但是<Authorizing> 的指令很有趣。:) - Bennyboy1973

0
这是一个简单的修复,实际上与授权无关。你在导航部分做得没错。问题在于由于某种原因,你不能在OnInitialized()中使用NavigationManager.NavigateTo()。它总是会抛出这个异常,你可能已经发现了。
但好消息是:解决方法很简单,虽然不是很惊艳:你只需将NavigationManager.NavigateTo()移到OnAfterRender()中。该方法在组件渲染后被调用,所以足够接近了。不过你需要处理页面的渲染方式。 this问题的答案也能回答你的问题。

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