Blazor:Read/observe 从任何地方查询参数

Blazor: Read/observe query parameter from anywhere

出于 SEO 考虑,我有一个现有的 ASP.NET 核心 + angular 应用程序需要转换为 blazor 服务器应用程序。

现有的 angular 应用程序监视 lang 查询参数并相应地更改 ui 语言。我做了一个最小的复制品 in the following repository.

在 AppComponent 中,查询参数被监视并更改整个应用程序的语言:

constructor(private route: ActivatedRoute, private translateService: TranslateService) {
  const defaultLang = 'en';
  this.route.queryParams.subscribe((params) => {
    const lang = params['lang'];
    if (!!lang) {
      this.translateService.use(lang);
    } else {
      this.translateService.use(defaultLang);
    }
  });
}

现在类似的行为应该应用于 blazor 应用程序,但我无法从 AppComponent.

中找到如何监视查询参数

Here is a repository with the VS solution

这是AppComponent的代码,我关注的是lang查询参数。

@using System.Globalization
<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>
<p>Current language: @Language, @language</p>

@code {

    private string language;
    [Parameter]
    [SupplyParameterFromQuery(Name = "lang")]
    public string Language
    {
        get => language;
        set
        {
            Console.WriteLine("Culture has been set to " + value);
            language = value;
            CultureInfo.CurrentCulture = CultureInfo.CurrentUICulture = new CultureInfo(value);
        }
    }
}

在所有页面上我都有以下代码:

@page "/xxx"

<p>Language: @Language</p>

@code {
    ...

    [Parameter]
    [SupplyParameterFromQuery(Name = "lang")]
    public string Language { get; set; }
}

这很好用。但是,将相同的代码放在 AppComponent 上是行不通的,因为 SupplyParameterFromQuery 仅在路由上下文中有效。

如何在 Blazor 应用中正确读取和观察查询参数?提前致谢

阅读您更新后的问题后,我想我可以提供一个可行的解决方案。

这将是 App.razor 的结构:

<CascadingValue Value="AppCountry">
    <CascadingAuthenticationState>
        <Router AdditionalAssemblies="@lazyLoadedAssemblies" AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true" OnNavigateAsync="@OnNavigateAsync">
            <Found Context="routeData">
                <AuthorizeRouteView RouteData="@routeData" DefaultLayout="typeof(SharedLayout.MainLayout)">
                    <NotAuthorized>
                        @if (!context.User.Identity.IsAuthenticated)
                        {

                        }
                        else
                        {
                            <p>You are not authorized to access this resource.</p>
                        }
                    </NotAuthorized>
                </AuthorizeRouteView>
            </Found>
            <NotFound>
                <LayoutView Layout="@typeof(SharedLayout.MainLayout)">
                    <p>Sorry, there's nothing at this address.</p>
                </LayoutView>
            </NotFound>
        </Router>
    </CascadingAuthenticationState>
</CascadingValue>

注意路由器组件中的 OnNavigateAsync 事件。该事件应如下所示:

private async Task OnNavigateAsync(NavigationContext args)
{
   
}

每次您在应用程序中导航时都会触发此事件。您有两个选择:

  1. App.razor中注入HttpClient并使用它来获取查询参数。
  2. 使用args.Path。这 return 是基地址之后的所有内容。例如 www.example.com/index?lang=en-US 它将 return index?lang=en-US.

进行所有必要的检查并改变您的文化。

可以找到有关全球化和本地化的更多信息here