You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Razor类库中的Razor页面统一添加路由前缀?

Blazor多模块RCL统一添加路由前缀方案

下面提供两种实用方案,无需手动修改每个页面的@page指令,就能给RCL内所有路由页面统一添加前缀:

方案一:.NET 7+ 项目文件配置(最简)

从.NET 7开始,Blazor原生支持给RCL设置全局路由基址,直接修改RCL的.csproj文件即可:

<PropertyGroup>
    <!-- 设置当前RCL的路由前缀,比如客户模块设为Customers -->
    <BlazorRouteBasePath>Customers</BlazorRouteBasePath>
</PropertyGroup>

配置后,该RCL内所有页面的@page路由会自动拼接前缀:

  • 原页面@page "/Details/{id}"
  • 实际访问路径变为localhost:5000/Customers/Details/1

每个模块的RCL单独配置对应的BlazorRouteBasePath即可实现路由隔离。

方案二:自定义路由约定(兼容低版本/灵活扩展)

如果使用.NET 6及以下版本,或者需要更灵活的路由修改逻辑,可以通过自定义IComponentModelConvention实现:

1. 创建路由约定类

在RCL项目中添加如下类,用于给路由添加前缀:

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using System.Reflection;

public class ModuleRoutePrefixConvention : IComponentModelConvention
{
    private readonly string _prefix;
    private readonly Assembly _moduleAssembly;

    public ModuleRoutePrefixConvention(string routePrefix, Assembly moduleAssembly)
    {
        _prefix = routePrefix.Trim('/');
        _moduleAssembly = moduleAssembly;
    }

    public void Apply(ComponentModel model)
    {
        // 仅处理当前RCL内的路由组件(带@page指令的组件)
        if (model.Type.Assembly != _moduleAssembly) return;
        var routeAttributes = model.Type.GetCustomAttributes<RouteAttribute>(inherit: true);
        if (!routeAttributes.Any()) return;

        // 替换原有路由为带前缀的新路由
        model.RouteValues.Clear();
        foreach (var routeAttr in routeAttributes)
        {
            var originalRoute = routeAttr.Template.Trim('/');
            var prefixedRoute = $"{_prefix}/{originalRoute}";
            model.RouteValues.Add(prefixedRoute);
        }
    }
}

2. 注册路由约定

在宿主项目(Blazor Server/WASM)的Program.cs中,注册该约定并指定前缀:

// 引用客户模块RCL的程序集
var customerModuleAssembly = typeof(CustomerModule.Pages.Details).Assembly;

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents() // 根据项目类型选择Server/WASM
    .AddAdditionalAssemblies(customerModuleAssembly)
    .AddComponentModelConvention<ComponentBase>(
        new ModuleRoutePrefixConvention("Customers", customerModuleAssembly)
    );

也可以在RCL中封装扩展方法,简化宿主项目的调用:

// 客户模块RCL内的扩展方法
public static class CustomerModuleExtensions
{
    public static RazorComponentsBuilder AddCustomerModule(this RazorComponentsBuilder builder)
    {
        var assembly = typeof(CustomerModuleExtensions).Assembly;
        builder.AddAdditionalAssemblies(assembly);
        builder.AddComponentModelConvention<ComponentBase>(
            new ModuleRoutePrefixConvention("Customers", assembly)
        );
        return builder;
    }
}

// 宿主项目Program.cs调用
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddCustomerModule();

注意事项

  • 两种方案都不需要修改RCL内页面的@page指令,原有路由模板保持不变即可。
  • 若使用方案二,确保仅处理目标RCL的组件,避免影响宿主项目或其他模块的路由。

内容的提问来源于stack exchange,提问作者quintendc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:42:43