手动刷新时带有参数的 Blazor 服务器页面会抛出 "404 找不到" 错误

8
我有一个使用Blazor Server的应用程序,其中一个页面在URI中接收参数。当我单击具有路由设置以带有参数命中该页面的锚标记(如下所示)时,链接正常工作,并且页面加载。
<a href="/MyPage/{@Param1}/{@Param2}"> <!--link content in here--> </a>

然而,如果直接从该URL访问页面或在浏览器中手动刷新页面,则页面不会重新初始化或命中任何参数上的断点。相反,它会抛出404未找到错误。
因此,有两个问题:
首先,我对为什么从锚标签内部正常工作但以其他方式运行感到困惑。特别是当没有在@page指令中使用params的页面可以通过刷新/直接URL正常工作时。
其次,这是Blazor Server的预期行为还是我错过了某些东西,导致页面刷新/直接URL失败?似乎不是一个功能,但也许我误解了Blazor的路由。
涉及页面的Razor和Razor.cs:
@page "/MyPage/{Param1}/{Param2}"

<h1>MyPage</h1>

<Metrics Param1="@Param1" />

<Details Param1="@Param1" Param2="@Param2" />

<InProgress Param1="@Param1" Param2="@Param2" />

<InQueue Param1="@Param1" />

<br />

using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
using MyApp.Data.Models.ApiResponse;

namespace MyApp.Pages
{
    public partial class MyPage
    {
        [Parameter]
        public string Param1 { get; set; }

        [Parameter]
        public string Param2{ get; set; }

        public TaskList Tasks { get; set; }

        protected override Task OnInitializedAsync()
        {
            // work in progress, intend to do more here later on
            var test = "";
            return base.OnInitializedAsync();
        }
    }
}

编辑-根据评论建议

在Startup.cs中Configure方法的UseEndpoints部分:

 app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });

进一步调查后,我注意到 @param2 中偶尔会有一个 . 字符。Blazor确实需要配置具有params with dots in them的路由。以下备用方案无效:
endpoints.MapFallbackToPage("/MyPage/{Param1}/{Param2}", "/MyPage");

这会抛出一个错误: InvalidOperationException: Cannot find the fallback endpoint specified by route values: { page: /MyPage, area: }.

我猜测 area: 为空是一个问题,但我找不到在哪里或如何正确地设置它。链接中的示例仅显示页面名称作为回退。请问有人能指出这个回退的问题在哪里以及如何正确地纠正它吗?


1
另外,我想回应你的评论:“首先,我对为什么在锚标签内可以正常工作感到困惑”——在锚标签中它可以正常工作是因为在那种情况下页面不会从服务器刷新。 - Kirk Woll
这看起来对我来说都很好。这是一个.NET 5项目吗?它使用最新的项目模板吗?当您从头开始创建全新的服务器端项目时,输入任意URL是否有效?(它应该显示一个Blazor页面,上面写着“抱歉,此地址没有内容”--但不是字面上的404) - Kirk Woll
@KirkWoll 这是一个使用最新的Blazor Server .NET 5项目(据我所知)。我想我找到了问题所在,我注意到@param2中偶尔会有句号。然而,备用方案似乎没有起作用 - 我将在一分钟内更新问题以反映这一点。 - CoderLee
1
哦,我认为你有点眼光独到。当我在URL中添加一个句号时,我复制了您的行为。 - Kirk Woll
1
@KirkWoll 那个尾随的斜杠似乎没有起作用,但指定 _Host 而不是页面就解决了问题。感谢您的帮助! - CoderLee
显示剩余4条评论
1个回答

9

我的问题是参数的值中带有一个点字符。当路由问题来自于参数中有一个"点"时,按照文档所建议的方式就可以解决问题了。您需要像下面这样为该特定路由指定一个回退:

endpoints.MapFallbackToPage("/MyPage/{Param1}/{Param2}", "/_Host");

对于WASM项目:您需要指定与_Host不同的html文件,这应该是特定于Blazor服务器的。
endpoints.MapFallbackToFile("/MyPage/{Param1}/{Param2}", "index.html");

当这个设置应用后,刷新页面或直接访问URL应该会使应用程序正常工作,不再出现404错误(与<NotFound>标签在App.razor中的设置不同)。

要点:

  • 检查您的URL参数是否存在已知的解析异常,例如点(Blazor认为这是请求文件)
  • 使用应用程序的默认页面作为回退选项,而不是您想要打开的页面。在服务器应用程序中,这是_Host ,在wasm中,则是 index.html

添加“/_Host”对我没有解决问题。我传递了一个带有几个点(IP地址)的字符串。我的做法是在链接中用连字符替换点,然后在目标页面上将它们替换回来。 - goodfellow
2
非常感谢@CoderLee。提供的链接非常有帮助,我的情况也是参数中的一个点。所以我最终使用了以下代码: endpoints.MapFallbackToPage("/{param1?}/{param2?}/{param3?}/{param4?}", "/_Host"); 它运行得非常好。 - ssamko

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