向 Blazor Web Assembly 全局添加路由前缀

问题描述 投票:0回答:1

我正在从事支持多语言的 Blazor Web Assembly 项目。要求是将语言添加到 URL 作为第一段。

我添加了本地化和资源文件,一切似乎都工作正常,但我必须向每个页面上的每个路由添加前缀才能识别该页面。

@page "/{lang}/counter"

@code {

    [Parameter]
    public string Lang { get; set; }
}

有没有办法全局添加前缀

/{lang}
,默认情况下将应用于所有路由,并且可以将该值设置为可注入服务?

谢谢,编码愉快

routes blazor url-routing blazor-webassembly
1个回答
0
投票

在我的项目中,我还需要在 URL 的第一段中使用语言前缀。经过很长时间的搜索,通过 URL 中的第一段来简化多语言支持的路由组件的创建,我找到了唯一的解决方案 - 使用 T4 为路由组件生成 Route 属性。

下面是这个T4文件。其中只需要填写输入数据即可:

  1. 应用程序中使用的一系列语言。可以有任意数量的语言。
  2. 一个数组,其中包含路由组件的类名称及其路由。

更改输入数据后,需要重新生成T4文件以获得一个.cs文件,其中包含路由组件的分部类及其Route属性。

为了方便起见,我建议将 T4 文件放在 Pages 文件夹中,所有可路由组件都位于该文件夹中。

附注要通过第一个 URL 段在 Blazor 服务器中提供多语言支持,我建议您阅读这篇文章: https://plbonneville.com/blog/url-based-localization-scheme-for-blazor-server/

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#  // Input data
    /// <summary>List of prefix language segments for all routes</summary>
    string[] languages = new string[] { "ru", "uz", "en" };

    /// <summary>Name for project namespace</summary>
    string nameSpace = "Manager.Pages";

    /// <summary>Data for generating routable components</summary>
    RoutableComponents[] routableComponents = new RoutableComponents[] {
        new RoutableComponents {
            Name = "Index",
            FixedRoutes = new string[] {
                "/"
            },
            Routes = new string[] {
                ""
            }
        },
        new RoutableComponents {
            Name = "Counter",
            FixedRoutes = new string[] {
                "/counter"
            },
            Routes = new string[] {
                "/counter",
                "/counter/{Segment1?}",
                "/counter/{Segment1}/{Segment2?}/{*Segments}",
            }
        },
        new RoutableComponents {
            Name = "FetchData",
            FixedRoutes = new string[] {
                "/fetchdata"
            },
            Routes = new string[] {
                "/fetchdata",
                "/fetchdata/{Segment1?}",
                "/fetchdata/{Segment1}/{Segment2?}/{*Segments}",
            }
        }
    };
#>
<#  // The code generation
    Write("using Microsoft.AspNetCore.Components;\n\n");
    Write("namespace {0};\n\n", nameSpace);

    foreach(var component in routableComponents) {
        foreach(var route in component.FixedRoutes) {
            Write("[Route(\"{0}\")]\n", route);
        }
        foreach(var route in component.Routes) {
            foreach(var language in languages) {
                Write("[Route(\"/{0}{1}\")]\n", language, route);
            }
        }
        Write("public partial class {0} : ComponentBase {{ }}\n\n", component.Name);
    }
#>

<#+
    public struct RoutableComponents {
        public string Name;
        public string[] FixedRoutes;
        public string[] Routes;
    }
#>

结果是以下 .cs 文件:

using Microsoft.AspNetCore.Components;

namespace Manager.Pages;

[Route("/")]
[Route("/ru")]
[Route("/uz")]
[Route("/en")]
public partial class Index : ComponentBase { }

[Route("/counter")]
[Route("/ru/counter")]
[Route("/uz/counter")]
[Route("/en/counter")]
[Route("/ru/counter/{Segment1?}")]
[Route("/uz/counter/{Segment1?}")]
[Route("/en/counter/{Segment1?}")]
[Route("/ru/counter/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/uz/counter/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/en/counter/{Segment1}/{Segment2?}/{*Segments}")]
public partial class Counter : ComponentBase { }

[Route("/fetchdata")]
[Route("/ru/fetchdata")]
[Route("/uz/fetchdata")]
[Route("/en/fetchdata")]
[Route("/ru/fetchdata/{Segment1?}")]
[Route("/uz/fetchdata/{Segment1?}")]
[Route("/en/fetchdata/{Segment1?}")]
[Route("/ru/fetchdata/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/uz/fetchdata/{Segment1}/{Segment2?}/{*Segments}")]
[Route("/en/fetchdata/{Segment1}/{Segment2?}/{*Segments}")]
public partial class FetchData : ComponentBase { }
© www.soinside.com 2019 - 2024. All rights reserved.