Как вручную отобразить страницу Blazor-Webassembly-404-Not-Found, если маршрут совпадает, но параметры неверны?

Представьте, это путь к моей странице Blazor: @page "/a/b/c/{numericvalue:int}"

Следующие запросы будут соответствовать:

/a/b/c/1
/a/b/c/2
/a/b/c/509

Этот запрос...

/a/b/c/test

... отобразит страницу NotFound, определенную в файле App.razor:

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

Но теперь я хочу, чтобы отвергли и нечетное число. Как я могу отобразить страницу NotFound вручную после того, как узнал, что номер нечетный? Мой код выглядит так:

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

1 ответ

Я изучил это из любопытства, и мой первый подход будет заключаться в создании пользовательского IRouteConstraint, как в MVC. Однако ограничения маршрута не работают в Blazor, и просмотр исходного кода показывает, что компонент Router имеет жестко закодированный список ограничений маршрута для страниц.

Однако я придумал обходной путь, и если у вас нет большого количества этих пользовательских ограничений, то я полагаю, что это работоспособное решение. Что вы делаете, так это вставляете некоторую пользовательскую логику в раздел Found маршрутизатора и перенаправляете обработанный вывод в NotFound в соответствии с вашим собственным условным потоком.

Следующий измененный App.razor гарантирует, что параметр маршрута Number для страницы Even всегда является четным числом, и будет отображать содержимое 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>
    };
}
Другие вопросы по тегам