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

多.NET Core Razor Web项目解决方案:路由跳转与视图配置问题咨询

多.NET Core Razor Web项目路由跳转+独立视图的实践方案

核心思路

不用把子项目的Views硬塞到主项目里,通过主项目的路由转发把特定前缀的请求(比如/Accounting/)导向子项目的控制器,同时给Razor视图引擎配置子项目的视图查找路径,让它能找到子项目自己的Views。

具体实现步骤

1. 子项目轻量化(可选但推荐)

如果子项目不需要单独启动运行,建议把AccountingWeb这类子项目从ASP.NET Core Web App改成ASP.NET Core Razor Class Library——这样不用每个子项目都写一套Program.cs,更适合模块化拆分。要是你坚持用Web项目也没问题,后续调整启动逻辑就行。

2. 主项目配置路由与视图引擎

在Mainweb的Program.cs里,先把所有子项目的程序集加进来,再给视图引擎指定子项目的视图路径,最后配置路由映射:

var builder = WebApplication.CreateBuilder(args);

// 注册所有子项目的控制器程序集
builder.Services.AddControllersWithViews()
    .AddApplicationPart(typeof(AccountingWeb.Controllers.ArticleController).Assembly)
    .AddApplicationPart(typeof(InventoryWeb.Controllers.XXXController).Assembly)
    // 其他子项目依次加进来
    .AddRazorOptions(options =>
    {
        // 告诉视图引擎去哪找子项目的视图
        options.ViewLocationFormats.Add("/AccountingWeb/Views/{1}/{0}.cshtml");
        options.ViewLocationFormats.Add("/InventoryWeb/Views/{1}/{0}.cshtml");
        options.ViewLocationFormats.Add("/CRMWeb/Views/{1}/{0}.cshtml");
        // 要是子项目多,也可以写个循环动态加载,不用一个个手动加
    });

var app = builder.Build();

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    // 主项目自己的默认路由
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    // 子项目路由:/Accounting/xxx/xxx 导向AccountingWeb的控制器
    endpoints.MapControllerRoute(
        name: "accounting",
        pattern: "Accounting/{controller}/{action}/{id?}",
        defaults: new { controller = "Article", action = "Index" });

    // 其他子项目照猫画虎
    endpoints.MapControllerRoute(
        name: "inventory",
        pattern: "Inventory/{controller}/{action}/{id?}");
});

app.Run();

3. 确保子项目视图能被主项目访问

先给子项目弄好标准的Views结构,比如AccountingWeb的结构:

AccountingWeb/
└── Views/
    └── Article/
        └── Index.cshtml

然后在Mainweb的.csproj文件里加一段配置,把这些视图文件复制到主项目的输出目录,不然运行时找不到:

<ItemGroup>
  <!-- 引用AccountingWeb的所有视图文件 -->
  <Content Include="..\AccountingWeb\Views\**\*.cshtml">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <Link>AccountingWeb/Views/%RecursiveDir%/%Filename%.%Extension%</Link>
  </Content>
  <!-- 其他子项目的视图也这么加 -->
</ItemGroup>

4. 独立部署子项目的方案(适合大型项目)

如果每个子项目需要单独部署(比如各自是独立的服务),可以用Yarp反向代理,让Mainweb做入口转发请求。

先装包:

Install-Package Yarp.ReverseProxy

然后在Mainweb的Program.cs里配置反向代理:

var builder = WebApplication.CreateBuilder(args);

// 添加反向代理服务
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));

var app = builder.Build();

app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapReverseProxy());

app.Run();

再在appsettings.json里写路由规则:

{
  "ReverseProxy": {
    "Routes": {
      "accounting_route": {
        "ClusterId": "accounting_cluster",
        "Match": {
          "Path": "/Accounting/{**catch-all}"
        },
        "Transforms": [
          { "PathRemovePrefix": "/Accounting" }
        ]
      },
      "inventory_route": {
        "ClusterId": "inventory_cluster",
        "Match": {
          "Path": "/Inventory/{**catch-all}"
        },
        "Transforms": [
          { "PathRemovePrefix": "/Inventory" }
        ]
      }
    },
    "Clusters": {
      "accounting_cluster": {
        "Destinations": {
          "accounting_service": {
            "Address": "http://localhost:5001/" // AccountingWeb的部署地址
          }
        }
      },
      "inventory_cluster": {
        "Destinations": {
          "inventory_service": {
            "Address": "http://localhost:5002/" // InventoryWeb的部署地址
          }
        }
      }
    }
  }
}

这种方式下,每个子项目完全独立,自己管自己的Views和逻辑,主项目只负责把请求转过去就行。

踩坑提示

  • 视图找不到:先检查RazorOptions里的路径对不对,再确认子项目的视图文件有没有被复制到主项目输出目录。
  • 路由冲突:主项目和子项目的路由前缀要区分开,别都用/Home/这种通用前缀。
  • 共享配置:比如数据库连接、身份验证这些核心配置,放在Mainweb里,子项目直接引用主项目的类库或者共享配置文件就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:25:33