Blazor 服务器路由前缀动态

Blazor server route prefix dynamic

我有一个 Blazor 服务器应用程序,我们需要设置一个全局路由前缀,我们可以使用它来根据前缀设置特定数据。有解决办法吗?

例如。我们想要这个 /company/{companyID}/ 在每条路线上都有一个中间件或类似的东西,将 companyID 放入。

endpoints.MapGet("/company/{companyID:regex(^[a-zA-Z]{{3,100}}(-[a-zA-Z+]{{3,100}})?$)}/{**rest}", async context =>
                {
                    var companyID = context.Request.RouteValues["companyID"]?.ToString()?.ToLower() ?? "default";
                    var restPath = context.Request.RouteValues["rest"]?.ToString()?.ToLower();

// Here i do stuff with the CompanyID
                    
                    // This is for now, but will redirect to /index without company/companyID. Here i just want to go on with the Ondex component and keep the url.
                    context.Response.Redirect(restPath == null ? "/" : $"/{restPath}");
                });
                
                endpoints.MapControllers();
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");

这可能符合您的要求。它使用 LocalStorage 来保存公司名称而不是 cookie。我已经使用 Blazor Server 模板进行了设置。

安装Blazored.LocalStorage

首先是公司服务

using Blazored.LocalStorage;

namespace Blazor.Company;

public class CompanyService
{
    private ILocalStorageService _localStorageService;

    public const string CompanyNameKey = "CompanyName";

    public string CompanyName { get; private set; } = string.Empty;

    public CompanyService(ILocalStorageService localStorageService)
        => _localStorageService = localStorageService;

    public async Task SetCompany(string company)
    {
        this.CompanyName = company;
        await _localStorageService.SetItemAsync<string>(CompanyNameKey, company);
    }

    public async Task<string> GetCompany()
    {
        this.CompanyName = await _localStorageService.GetItemAsync<string>(CompanyNameKey);
        return this.CompanyName;
    }
}

程序如下所示:

builder.Services.AddBlazoredLocalStorage();
builder.Services.AddScoped<CompanyService>();

Index 看起来像这样:

page "/"
@page "/Company"
@page "/Company/{CompanyName}"

<PageTitle>Index</PageTitle>

@if (this.hasCompany && this.isSet)
{
    <div class="m-2 p-4 bg-success text-white">
        <h3>You work for : @CompanyService.CompanyName</h3>
    </div>
}
@if (this.isSet && !this.hasCompany)
{
    <div class="m-2 p-4 bg-danger text-white">
        You need to set up your company
    </div>
}

@code {
    [Parameter] public string CompanyName { get; set; } = string.Empty;

    private string companyName = string.Empty;

    private bool isSet = false;
    private bool hasCompany => !string.IsNullOrWhiteSpace(this.companyName);

    [Inject] private CompanyService? companyService { get; set; }
    private CompanyService CompanyService => companyService!;

    protected override void OnInitialized()
    {
        if (!string.IsNullOrWhiteSpace(this.CompanyName))
            companyName = this.CompanyName;
    }

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            if (string.IsNullOrWhiteSpace(this.companyName))
                companyName = await CompanyService.GetCompany();
            else
                await CompanyService.SetCompany(companyName);

            this.isSet = true;
            StateHasChanged();
        }
    }
}