跳转至

尝试使用

引言

在Blazor项目中安装BlazorPathHelper

安装BlazorPathHelper
1
dotnet add package BlazorPathHelper

URL生成器

最简URL生成器

创建一个文件,文件名可以随意,但为了说明方便,我们称之为WebPaths.cs

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
using BlazorPathHelper;

// 通过添加BlazorPath属性,自动生成将会进行。
// 此外,在定义类时必须使用partial属性。
[BlazorPath]
public partial class WebPaths
{
  // 通过常量定义URL页面。
  // public const string (变量名) = "/your-path";
  public const string Index = "/";
  public const string Sample = "/sample";
  public const string SampleChild = "/sample/child";
  public const string Counter = "/counter";
  public const string CounterWithState = "/counter/{count:int}";
  public const string CounterWithQuery = "/counter/query";
}

这样定义后,以下类定义将自动生成。

自动生成的URL生成器
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// <auto-generated />
public partial class WebPaths
{
  // 在Helper类中生成URL生成器
  public partial class Helper
  {
    public static string Index() => "/";
    public static string Sample() => "/sample";
    public static string SampleChild() => "/sample/child";
    public static string Counter() => "/counter";
    public static string CounterWithState(int Count)
      => string.Format("/counter/{0}", ToStringForUrl(Count));
    public static string CounterWithQuery() => "/counter/query";
  }
}

WebPaths.Helper.CounterWithState生成了一个接受int类型参数的URL生成器。
然而,CounterWithQuery尚未定义为接受查询参数的形式。
这是因为尚未定义要接受哪些查询参数。

带查询的URL生成器

现在,我们来定义一个可以接受查询参数的URL生成器。

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
using BlazorPathHelper;

[BlazorPath]
public partial class WebPaths
{
  public const string Index = "/";
  public const string Sample = "/sample";
  public const string SampleChild = "/sample/child";
  public const string Counter = "/counter";
  public const string CounterWithState = "/counter/{count:int}";
  [Query<QueryRecord>] // 指定Query属性
  public const string CounterWithQuery = "/counter/query";
}

// 定义一个接收查询参数的类。
// 此类必须在.cs文件中编写。(参见下方注释)
// 建议为每个参数指定默认值或将其设为可空。
public record QueryRecord(string query = "hello", int page = 0, bool? opt = null);

注意!

上述QueryRecord类定义如果写在.razor文件中将无法正确生成。
这是由于源代码生成器的特性所致。(Razor文件也通过源代码生成器转换为C#,因此会发生冲突。)

这样,以下类定义将自动生成。

自动生成的URL查询生成器
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// <auto-generated />
public partial class WebPaths
{
  public partial class Helper
  {
    // 省略公共部分
    public static string CounterWithQuery(QueryRecord __query)
      => string.Format("/counter/query{0}", BuildQuery([
        ToEscapedStrings("query", __query.query),
        ToEscapedStrings("page", __query.page),
        ToEscapedStrings("opt", __query.opt)
      ]));
  }
}

这样,CounterWithQuery的URL生成器就可以接收查询参数了。
有关查询定义的详细信息,请参阅查询支持

使用方法

(类名).Helper.(变量名)是URL生成器函数。可以如下使用:

Usage.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 调用函数生成URL
var homeUrl = WebPaths.Helper.Index();
// 带参数
var counterStateUrl = WebPaths.Helper.CounterWithState(1);
// 带查询
var counterQueryUrl1 = WebPaths.Helper.CounterWithQuery(new());
var counterQueryUrl2 = WebPaths.Helper.CounterWithQuery(new() { query = "test" });
var counterQueryUrl3 = WebPaths.Helper.CounterWithQuery(new() { query = "foo", page = 1, opt = true });

Console.WriteLine(homeUrl);          // -> "/"
Console.WriteLine(counterStateUrl);  // -> "/counter/1"
Console.WriteLine(counterQueryUrl1); // -> "/counter/query?query=hello&page=0"
Console.WriteLine(counterQueryUrl2); // -> "/counter/query?query=test&page=0"
Console.WriteLine(counterQueryUrl3); // -> "/counter/query?query=foo&page=1&opt=true"

// 导航到另一个页面
// @inject NavigationManager Nav
Nav.NavigateTo(counterStateUrl);

有关更详细的使用方法,请参阅URL生成器的使用方法

自动页面属性指定

在Blazor页面中需要指定@page[Parameter][SupplyParameterFromQuery]等属性,但这些也可以根据URL定义信息自动生成。

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using BlazorPathHelper;
using Microsoft.AspNetCore.Components;

[BlazorPath]
public partial class WebPaths
{
  [Page<Home>] // <- 添加Page<页面组件>属性
  public const string Index = "/";
  [Page<Sample>]
  public const string Sample = "/sample";
  [Page<SampleChild>]
  public const string SampleChild = "/sample/child";
  [Page<Counter>]
  public const string Counter = "/counter";
  [Page<Counter2>]
  public const string CounterWithState = "/counter/{count:int}";
  [Page<Counter3>, Query<QueryRecord>]
  public const string CounterWithQuery = "/counter/query";
}

public record QueryRecord(string query = "hello", int page = 0, bool? opt = null);
// 各组件的定义(实际上是在各组件中编写)
public partial class Home : ComponentBase;
public partial class Sample : ComponentBase;
public partial class SampleChild : ComponentBase;
public partial class Counter : ComponentBase;
public partial class Counter2 : ComponentBase;
public partial class Counter3 : ComponentBase;

这样,包含@page[Parameter][SupplyParameterFromQuery]类定义的文件将自动生成。

自动生成的页面定义文件(折叠)
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// <auto-generated />
// -------------------
// Index(Home)
[Route("/")] // -> 等同于在razor文件中写[@page "/"]
public partial class Home;

// 中略

// CounterWithState(Counter2)
[Route("/counter/{count:int}")]
public partial class Counter2
{
  // 自动生成参数定义
  [Parameter]
  public int Count { get; set; }
}
// -------------------
// CounterWithQuery(Counter3)
[Route("/counter/query")]
public partial class Counter3
{
  // 自动生成查询参数定义
  [SupplyParameterFromQuery]
  public string Query { get; set; }
  [SupplyParameterFromQuery]
  public int Page { get; set; }
  [SupplyParameterFromQuery]
  public bool? Opt { get; set; }
}

这样,页面属性将自动设置,因此.razor文件中的描述不再需要。
因此,可以从.razor文件中删除@page属性等。
有关详细使用方法,请参阅自动页面属性

随时可移除

通过[Page]属性指定的自动生成是完全独立的功能。
因此,如果不需要自动定义,可以随时删除[Page]属性。

自动生成菜单结构

基于URL定义,菜单结构数据也将自动生成。这对于动态创建菜单非常有用。

最简菜单生成

在每个URL定义中添加[Item]属性。

WebPaths.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using BlazorPathHelper;

[BlazorPath]
public partial class WebPaths
{
  // 通过添加[Item("菜单名")]属性,自动生成将会进行。
  // [Page]/[Query]属性是完全独立的,因此可以同时使用。
  [Item("主页")]
  public const string Index = "/";
  [Item("示例1a")]
  public const string Sample = "/sample";
  [Item("示例1b")]
  public const string SampleChild = "/sample/child";
  [Item("示例2a")]
  public const string Counter = "/counter";
  // 带参数/查询的页面不应显示在菜单中,因此省略了[Item]属性。
  // (即使设置了,也会自动从菜单中省略)
  public const string CounterWithState = "/counter/{count:int}";
}

这样,WebPaths.MenuItem中将自动生成菜单结构数据。

自动生成的菜单结构数据(折叠)
Auto Generated Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// <auto-generated />
public partial class WebPaths
{
  public static readonly BlazorPathMenuItem[] MenuItem = [
    new BlazorPathMenuItem(){
      Name = "主页", // 菜单名。如果未指定,将使用变量名
      Path = "/",       // 页面URL
      Children = []     // 子菜单
      // 还有一些其他自动生成的属性,方便菜单创建。
    },
    new BlazorPathMenuItem(){
      Name = "示例1a",
      Path = "/sample", 
      // 基于URL结构自动生成子菜单
      Children = [
        new BlazorPathMenuItem(){
          Name = "示例1b",
          Path = "/sample/child", 
          Children = []
        }
      ]
    },
    new BlazorPathMenuItem(){
      Name = "示例2a",
      Path = "/counter",
      Children = []
    }
  ]
}

在这里,仅生成了菜单结构数据,菜单显示需要另行实现。
也就是说,使用哪个框架来创建菜单由你决定!

有关详细信息,请参阅各框架的示例。

自定义

在生成菜单时,可以进行描述、图标、本地化等自定义。
详细信息请参阅菜单结构的自定义