【问题标题】:How to redirect to a different route in Blazor Server-side如何在 Blazor 服务器端重定向到不同的路由
【发布时间】:2019-01-04 18:11:34
【问题描述】:

在 Blazor 客户端中,可以使用实现重定向

using Microsoft.AspNetCore.Blazor.Browser.Services;
(...)
BrowserUriHelper.Instance.NavigateTo("/route")

但这在 Blazor 服务器项目中不起作用,因为它会生成以下错误:

无法将“Microsoft.AspNetCore.Blazor.Server.Circuits.RemoteJSRuntime”类型的对象转换为“Microsoft.JSInterop.IJSInProcessRuntime”类型。

Blazor-Server 中的重定向是什么样的?

【问题讨论】:

  • 问题,你为什么要在服务器上重定向到另一个控制器?你不能简单地执行你想要的方法吗?而不是路由到新的 HttpContext?否则,您将需要渲染部分视图并将其作为可再次渲染的某种形式的可访问数据传回。
  • 因此,当您创建服务器端项目时,您将获得服务器和客户端项目。我想在剃须刀页面的客户端应用程序中执行此操作。当用户单击按钮时,请求会发送到服务器,根据响应,我想重定向到不同的页面或保持当前状态。
  • 是的,但是当客户端点击事件在客户端内导航时,您会从客户端触发服务器端事件。客户端应用程序根据服务器给出的响应进行导航。然后客户端将根据服务器提供的响应使用适当的组件视图。
  • 所以服务器必须实际告诉客户端导航到不同的页面?那么如何在我的场景中实现呢?不知道有没有例子?
  • 对于非服务器端托管的 Blazor 实现,是的。对于 Blazor,目前我不必使用它。

标签: c# blazor-server-side


【解决方案1】:

如果可以在剃须刀页面触发,可以使用如下:

@page "/YourPageName"
@inject NavigationManager NavigationManager

<h1>xxx</h1>
.
.
.


@code {

    void MethodToTriggerUrl()
    {
        NavigationManager.NavigateTo("PageToRedirect");
    }
}

【讨论】:

  • 代替 MethodToTriggerUrl() 当然不会自动调用,你可以把 NavigationManager.NavigateTo("/PageToRedirect");进入受保护的覆盖 void OnInitialized(){},这将触发自动重定向。
  • 是的,你是对的,这完全取决于你的设计。如果你想自动重定向,你可以这样做。您甚至可以倒计时并在之后重定向。问题的答案只是NavigationManager.NavigateTo() :)
【解决方案2】:

经过一段时间的试验,我发现在服务器端这是有效的:

using Microsoft.AspNetCore.Blazor.Services;
(...)
UriHelper.NavigateTo("/route");

当然,看起来几乎一样,但确实有效(至少在 Blazor 0.8 中)

【讨论】:

  • 在 0.9 中,至少对我来说,我需要 @inject IUriHelper UriHelper
  • UriHelper 已重命名为 Microsoft.AspNetCore.Components 命名空间中的 NavigationManager@inject NavigationManager NavigationManager; NavigationManager.NavigateTo("route", false);
  • 我有一个 Blazor 服务器应用程序需要重定向到单独的 Blazor 组件库中的页面,NavigationManager 没用。由于某种原因它没有被初始化,我无法从服务器项目中的页面导航到库项目中的页面。
【解决方案3】:

不完全是您正在寻找的东西,但仍然是“解决方案”。我目前似乎无法找到一种方法,在服务器端执行类似于 Response.Redirect 的操作,但是使用 jsinterop,在您希望能够重定向 FROM 的组件中,使用类似这样的东西。请注意,我也很好奇,并且知道这也会出现在我自己身上,我做了以下事情:

所以基于带有服务器端项目模板的示例应用...

index.cshtml

@using Microsoft.JSInterop;

 <a href="#" class="btn btn-primary" onclick="@GoSomewhere">Go somewhere with Blazor</a>

@functions {
    protected void GoSomewhere()
    {
        RedirectTo("/FetchData");  //or any other "page" in your pages folder
    }

    public static Task<string> RedirectTo(string path)
    {
        return JSRuntime.Current.InvokeAsync<string>(
            "clientJsfunctions.RedirectTo", path);
    }    
}

然后,在 wwwwroot 文件夹下,放置一个带有以下内容的 javascript 文件:

window.clientJsfunctions = {       
    RedirectTo: function (path) {
        window.location = path;
    }
};

最后,在您的引导程序文件 index.html 中,放置对这个 js 文件的引用

<body>
    <app>Loading...</app>

    <script src="_framework/blazor.server.js"></script>

    <script src="scripts/ClientUtil.js"></script>
</body>

更好的是,将上面的“RedirectTo”等方法放在一个单独的类中,并将其用作大多数组件页面的基类。

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Blazor.Components;
using Microsoft.JSInterop;

namespace MyApp.Web.App.Shared
{
    public class MycomponentBase : BlazorComponent
    {
        public static Task<string> RedirectTo(string path)
        {
            return JSRuntime.Current.InvokeAsync<string>(
                "clientJsfunctions.RedirectTo", path);
        }
    }
}

另外,记得把它放在每个组件的顶部 @inherits 我的组件库;

现在,您应该有一个“重定向”方法,您可以从派生自您的基组件类的任何组件调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 2020-01-20
    相关资源
    最近更新 更多