.Net Core MVC Routing:根据每个控制器设置MapSpaFallbackRoute

Dav*_*vid 9 single-page-application asp.net-core-mvc asp.net-core-1.0 asp.net-core-middleware angular

我正在开发一个涉及多个单页应用程序的项目,这些应用程序托管在单个.Net Core 1.0 Web应用程序上.

目标是对每个SPA进行分区,使它们全部分开存在,每个SPA都有自己的视图和控制器.

在Startup.cs中,我使用Microsoft.AspNetCore.SpaServices MapSpaFallbackRoute传递到SPA的深层链接(在本例中为Angular 2),因此MVC不会混淆并在页面刷新时抛出404.

当我在MapSpaFallbackRoute中手动设置Controller时,我一次为一个SPA工作,但我无法找到为每个SPA控制器有条件地设置它的方法.

我假设Mapwhen()和Run()的组合将我带到我需要的位置,但我似乎无法使语法正确.

假设SPA被命名为'Dash1','Dash2'等.以下后备路由适用于Dash1:

 app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Dash1", action = "Index" });
        });
Run Code Online (Sandbox Code Playgroud)

我试过这个:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
        app.Map("/Dash1", HandleDash1);

    }

    private static void HandleDash1(IApplicationBuilder app)
    {
        app.UseMvc(routes =>
        {
            routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Dash1", action = "Index" });
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

...但是当我导航到Dash1并尝试刷新页面时,浏览器会将'/ Dash1 /'添加到所有http请求中并中断所有内容.

Dav*_*vid 19

我得到它与MapWhen()一起工作,但每个SPA都必须以这种方式注册.

app.MapWhen(context => context.Request.Path.Value.StartsWith("/Dash1"), builder =>
{
    builder.UseMvc(routes =>
    {
        routes.MapSpaFallbackRoute("dash1-fallback", new { controller = "Dash1", action = "Index" });
    });
});

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)

我正在使用此方法来托管Angular(2+)应用程序.我最初使用SystemJS并将所有应用程序保存在一个项目中,但在版本4发布时我转移到了Angular CLI.

我发现管理应用程序的最佳方法是在解决方案中为每个应用程序创建一个单独的项目,并使用NPM脚本将捆绑的文件复制到"主"项目的wwwroot内的文件夹中.

我只是提供CLI创建的静态html文件,而不是返回View,但是Views也正常工作.

public IActionResult Index()
{
    return PhysicalFile(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/dash1", "index.html"), "text/HTML");
}
Run Code Online (Sandbox Code Playgroud)

棘手的部分是管理路由器.您必须通过设置窗口['_ app_base']来设置基本href并将路由切换到Angular路由器,以对应当前控制器的路由.

在index.html中包含以下内容:

<head>
    // Set base href. 
    // You need to include the path if serving the static file from wwwroot
    // Use '/' if using a View (I think, I had to change this when I switched to static files).

    <base href="/dash1/"> 

    <script>
        (function () {
            // You could type the controller path here again but this will infer it.

            window['_app_base'] = '/' + window.location.pathname.split('/')[1];

        })();
    </script>
</head>
Run Code Online (Sandbox Code Playgroud)

然后,Angular路由器必须从窗口['_ app_base']获取它的方位.在app.module.ts中包含以下内容:

import { NgModule, Provider } from '@angular/core';
import { APP_BASE_HREF, Location } from '@angular/common';
const baseHref: Provider = {
    provide: APP_BASE_HREF,
    useValue: window['_app_base'] || '/'
};
Run Code Online (Sandbox Code Playgroud)

最后,在@NgModule的providers数组中包含baseHref.