Как вручную отобразить страницу 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>
};
}