Web applications can connect multiple pages in series through URLs, and can jump to each other. Web applications mainly use a tag or server redirect to jump. Now the popular single-page application (SPA) realizes the jump through routing (Router), such as Vue, React, etc.
提示
Routing in MAUI is very different from routing in Blazor.
Table of contents
Routing for MAUI Blazor
In .NET MAUI Blazor applications, routing is Blazor
the routing rule to follow. It is also implemented through the routing component (Router). Open it and Main.razor
you can see:
<Router AppAssembly="@typeof(Main).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
<!--设置容器-->
<AntContainer />
There Router
are two child nodes Found
with NotFound
.
- The Found node contains a definition of RouteView. If a route definition is found, the corresponding page will be presented through RouteView, and a default template will be specified for all pages.
- The NotFound node contains a LayoutView definition. If no routing definition is found, a specific page will be presented. The default template used here is that you
MainLayout
can also implement one yourself.
Define MAUI Blazor routes
In MAUI Blazor, routing definitions @page
are specified using directives. When creating Blazor
a component, it must be included @page '路径"
.
There is a big difference between MAUI routing and MAUI Blazor routing.
MAUI creates routes based on the Route attribute or through the explicit registration route through Routing.RegisterRoute.
MAUI Blazor is on the component, using the @page directive to specify.
When the Visual Studio 2022 compiler compiles a Razor component (.razor) with the @page directive, it will provide the component class with a RouteAttribute to specify the route of the component.
When the application starts, the application will scan the assembly specified by the AppAssembly attribute in the Router component, and collect the routing information of the Blazor components with RouteAttribute in the assembly.
When the application is running, the RouteView component:
- Receive RouteData from Router along with all route parameters.
- Renders the specified component using its layout, including any subsequent nested layouts.
Hint
Router does not interact with query string values.
When a route is matched
Based on the last code, we add a page. In Pages
the directory, create a new Blazor component: pdf.razor
. After creation, the default code is as follows:
<h3>pdf</h3>
@code {
}
We use @page
the directive to specify the route as pdf
. And write a few big characters.
@page "/PDF"
<Title Level="1">使用iTextSharp生成PDF文件</Title>
Then open it MainLayout.razor
and add one to the menu MenuDataItem
.
new MenuDataItem
{
Path = "/PDF",
Name = "PDF",
Key = "PDF",
Icon = "file-pdf"
}
Note:
Blazor components must start with an uppercase letter. If you start with a lowercase letter, an error will be reported when compiling:
Component 'xxx' starts with a lowercase character. Component names cannot start with a lowercase character
xxx is the name of the component.
Look at the effect of running:
When no route is matched
If no route is matched, NotFound
the content defined by the node above will be rendered. First NotFound
modify the content of the node a little bit!
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<div style="text-align:center"><Icon Type="close-circle" Theme="twotone" TwotoneColor="#ff0000" Height="5em" Width="5em" /></div>
<div style="margin-top:15px;text-align:center"><Title Level="3">页面走失!请确认输入的URL是否正确!</Title></div>
</LayoutView>
</NotFound>
In MainLayout.razor
, add one MenuDataItem
that points to a page that doesn't exist:
new MenuDataItem
{
Path = "/DataList",
Name = "DataList",
Key = "DataList",
Icon = "appstore"
}
Look at the running effect:
Routing Jump
In many scenarios, in addition to clicking the menu on the left to jump, you also need to jump on the page. In addition to HTML tags, the jump supported by Blazor <a></a>
also has a NavigationManager
class.
NavigationManager
Classes are Microsoft.AspNetCore.Components
under a namespace.
under transformation Index.razor
.
@page "/"
@inject NavigationManager navigationManager
<Title Level="1">Hello,DotNet宝藏库</Title>
<div style="margin-top:15px;"><Text Type="success">欢迎关注我的公众号!</Text></div>
<Divider />
<div style="margin-top:20px;"><a href="/Counter">使用a 标记跳转</a></div>
<div style="margin-top:20px;">
<Button Danger Type="@ButtonType.Primary" OnClick="()=>DirectToCounter()">使用NavigationManager跳转</Button>
</div>
@code
{
private void DirectToCounter()
{
navigationManager.NavigateTo("/Counter");
}
}
At this time, whether you click a link or a button, you can jump to the response page!
routing parameters
During the routing process, parameter passing is often required, so that we can perform some operations after jumping to the new page.
There are two types of Blazor parameter passing: path
parameter passing and QueryString
parameter passing. We introduce these two methods of passing parameters separately.
path parameter
Path parameter passing is to combine the parameters in the URL path, and the page that receives the parameters needs to @page
fill in the parameters with the same name. And add Parameter
features to modify the parameters.
Transform firstCounter.razor
@page "/counter"
@page "/counter/{initNum}"
<Title Level="2">Counter</Title>
<Divider />
<p role="status">Current count: @currentCount</p>
<Button @onclick="IncrementCount" Type="primary">AntDesign 按钮</Button>
@code {
[Parameter]
public string initNum{
get; set; }
private int currentCount = 0;
protected override void OnParametersSet()
{
if (!int.TryParse(initNum, out int num))
{
currentCount = 0;
}else
{
currentCount = num;
}
}
private void IncrementCount()
{
currentCount++;
}
}
In the code, one is added @page "/counter/{initNum}"
. {initNum}
It is the parameter.
Note that parameters are not case-sensitive , but for more standardization, it is recommended that all URLs be in lowercase, and c# codes should be named in camel case.
Also, Blazor
optional parameters are not supported, so if the initNum in this example is optional, you need to use @page
instructions to define two routes, one containing initNum
and the other not containing.
OnParametersSet
or OnParametersSetAsync
in, we initNum
assign to currentCount
.
Modify the method Index.razor
in the following DirectToCounter
:
private void DirectToCounter()
{
navigationManager.NavigateTo("/Counter/10");
}
When it runs, when 使用NavigationManager跳转
the button is clicked, Counter.razor
the currentCount in it is 10.
QueryString 传参
In addition to splicing parameters directly into the URL path (path), another common method of passing parameters is to pass parameters as QueryString to the jump page, such as "/Counter?initNum=3". We can get the query string of the request from the NavigationManager.Uri property.
change Index.razor
in
<a href="/Counter">使用a 标记跳转</a>
to<a href="/Counter?initNum=5">使用a 标记跳转</a>
Modify Counter.razor
, import first NavigationManager
.
@page "/counter"
@inject NavigationManager navigationManager
OnParametersSet
Get parameters inside
protected override void OnParametersSet()
{
//if (!int.TryParse(initNum, out int num))
//{
// currentCount = 0;
//}else
//{
// currentCount = num;
//}
var query = new Uri(navigationManager.Uri).Query;
Console.WriteLine(query);
}
After the breakpoint, you can see that after Index.razor
clicking the link to jump to Counter.razor
, the parameters are obtained:
there is a problem here, the obtained parameters are not key-value pairs, but a string of strings. Different from our expectations. But fortunately, we can QueryHelpers.ParseQuery
get the key-value pair information through .
1. Add dependencies:
PM> NuGet\Install-Package Microsoft.AspNetCore.WebUtilities -Version 2.2.0
2. Analyzing parameters
var queryDic = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
The parameter value can be obtained. Complete the code:
protected override void OnParametersSet()
{
//if (!int.TryParse(initNum, out int num))
//{
// currentCount = 0;
//}else
//{
// currentCount = num;
//}
var query = new Uri(navigationManager.Uri).Query;
var queryDic = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(query);
if (queryDic.ContainsKey("initNum"))
{
var count_str = queryDic["initNum"].ToString() ?? "";
if (!int.TryParse(count_str, out int num))
{
currentCount = 0;
}
else
{
currentCount = num;
}
}
else
{
currentCount = 0;
}
}
Run it to see the effect
routing constraints
Routing constraints enforce type matching between routing segments and components. As in the example just now initNum
, we can write @page "/counter/{initNum:int}"
that the routing constraint does not apply to the query string, which is the parameter passed by QueryString. Blazor supports the following constraint types:
- bool
- datetime
- decimal
- double
- float
- guid
- int
- long
Summarize
None yet, see you next time!
Click on the official account card below to follow me! Learn together and progress together!