如果路由匹配但参数错误,如何手动显示 Blazor-Web assembly-404-Not-Found 页面?

nds*_*svw 5 razor razor-pages blazor-webassembly

想象一下,这是通往我的 Blazor 页面的路线:@page "/a/b/c/{numericvalue:int}"

以下请求将匹配:

/a/b/c/1
/a/b/c/2
/a/b/c/509
Run Code Online (Sandbox Code Playgroud)

这个请求...

/a/b/c/test
Run Code Online (Sandbox Code Playgroud)

...将显示 App.razor 文件中定义的 NotFound 页面:

<NotFound>
    <LayoutView Layout="@typeof(MainLayout)">
        <p>Sorry, there's nothing at this address.</p>
    </LayoutView>
</NotFound>
Run Code Online (Sandbox Code Playgroud)

但现在我也希望奇数被拒绝。发现号码为奇数后,如何手动显示NotFound页面?我的代码如下所示:

@code{
    [Parameter]
    public int NumericValue {
        set => {
            if(value % 2 == 1)
                // show the 404 page
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Aki*_*eel 0

出于好奇,我对此进行了研究,我的第一个方法是像在 MVC 中那样制作自定义 IRouteConstraint。但是,路由约束在 Blazor 中不起作用,查看源代码会发现 Router 组件具有页面路由约束的硬编码列表。

然而,我想出了一个解决方法,如果您没有大量的自定义约束,那么我认为这是一个可行的解决方案。您要做的就是将一些自定义逻辑插入到 Router 的 Found 部分,并根据您自己的条件流将渲染的输出重定向到 NotFound。

以下修改后的 App.razor 将确保偶数页面的 Number 路由参数始终为偶数,如果为奇数,将显示 NotFound 内容:

<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true" NotFound="NotFound">
    <Found Context="routeData">
        @{
            bool found = true;
            var route = routeData;

            if (routeData.PageType.IsEquivalentTo(typeof(Pages.Even)))
            {
                if (routeData.RouteValues.TryGetValue("number", out var numberValue))
                {
                    var number = Convert.ToInt32(numberValue);

                    if (number % 2 != 0)
                    {
                        found = false;
                    }
                }
            }
        }
        @if (found)
        {
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        }
        else
        {
            @NotFound
        }
    </Found>
</Router>
@code
{
    private RenderFragment NotFound => __builder =>
    {
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    };
}
Run Code Online (Sandbox Code Playgroud)