从带有参数的 ASP.NET MVC 控制器中重定向到 Angular2 应用程序

Redirect to Angular2 app from within an ASP.NET MVC controller with parameters

我正在尝试从 MVC 控制器重定向到位于 MVC 项目区域内的 Angular 2 应用程序,结构如下:

Clients.Web (MVC project)
|
+--Areas
   |
   +--Legacy
   |  |
   |  +--Controllers
   |     |
   |     +--Action1ApiController
   |
   +--Web
      |
      +--app
      |  |
      |  +--action1
      |  |  |
      |  |  +--action1.component.ts
      |  |
      |  +--action2
      |  |  |
      |  |  +--action2.component.ts
      |  |
      |  +--app.component.ts
      |  +--index.html
      |  +--main.ts
      |
      +--assets (vendor modules, images etc.)
      +--Controllers
      |  |
      |  +--AppController.cs
      |
      +--node_modules
      +--typings
      |
     ...

我需要能够从遗留 MVC 页面遍历到 Angular 2 应用程序,例如

/Web/App/Action1?param1=10&param2=15

应该路由到

/Action1/:param1/:param2

在 Angular 中。同时,我需要能够在

上调用操作
/Areas/Legacy/Controllers/Action1ApiController

出于对饼干的热爱,我不知道该怎么做。在我的 index.html 中,我将 base href 设置为

<base href="/Areas/Web/">

在同一个文件中,我使用 SystemJS 导入了主模块,

<script>
  System.config({
     baseURL: './',
     map: {
        'angular2': '/Areas/Web/node_modules/angular2',
        'rxjs': '/Areas/Web/node_modules/rxjs'
     }
  });
  System.defaultJSExtensions=true;
  System.import('/Areas/Web/app/main')
     .then(null,console.error.bind(console));
</script>

然后我 bootstrap 应用程序

import { bootstrap } from 'angular2/platform/browser';
import { AppComponent } from './app.component';

bootstrap(AppComponent, [])
  .then(success => console.log('Bootstrap success'))
  .catch(error => console.log(error));

最后,在app.component我设置了路由

import { Component } from 'angular2/core';
import { ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, Route, Redirect } from 'angular2/router';
import { Component1} from './action1/action1.component';
import { Component2} from './action2/action2.component';

@Component({
    selector: "app",
    templateUrl: 'app/app.component.html',
    styleUrls: ['app/app.component.css'],
    directives: [
        ROUTER_DIRECTIVES,
        Action1Component, 
        Action2Component
    ],
    providers: [
        ROUTER_PROVIDERS
    ]  
})
@RouteConfig([
    new Route({ path: '/:param1/:param2, name: 'Action1', component: Action1Component})
])
export class AppComponent {
}

但是,如果我随后导航到

/Areas/Web/app/index.html?param1=10&param2=!5

我明白了

param1 = 'app'
param2 = 'index.html'

传递到 Action1Component,这显然不是我想要的。任何指针将不胜感激。

编辑:

路由目前只针对 AppController

routes.MapRoute("SPA", "Web/{controller}/{action}/{id}",
    new { controller = "App", action = "Index", area = "Web", id = UrlParameter.Optional },
    new[] { "SomeSite.Areas.Web.Controllers" }); 

操作代码为

public class AppController : Controller
{
   public ActionResult Index(int param1, int param2)
   {
       return Redirect($"/Areas/Web/app/index.html?param1={param1}&param2={param2}");
   }
}

因为我一次迁移一个旧网站,所以我的想法是在 AppController 和 link 上执行 Action1, Action2 等操作,这些操作来自遗留页面。

问题是,您的路由不匹配。

你说你想要路线

/Action1/:param1/:param2

要路由但给它

index.html?param1={param1}&param2={param2}

这完全不是一回事。此时的问题将出在您的 MVC 应用程序中,因为它将以 /Web 开头的所有流量重定向到控制器,从而创建 SPA 应用程序。但是 SPA 应用程序只会从 /Areas/Web/ 之后的点开始查看 url,因此从 \app 开始将其视为第一个参数,因为您已告诉它首先期望两个参数url.

public ActionResult Index(int param1, int param2)
{
   return Redirect($"/Areas/Web/app/index.html?param1={param1}&param2={param2}");
 }

应该是

public ActionResult Index(int param1, int param2)
{
   return Redirect($"/Areas/Web/param1/param2");
}

根据您的 Angular 应用程序,但这将开始一个新的路由循环和重定向,并最终陷入无限循环。

我通常在我的 MVC 应用程序中有一个操作只是通过返回 html 页面而不是重定向来创建 spa 应用程序,以避免在捕获所有内容之外进行路由。像这样

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return new FilePathResult("~/index.html", "text/html");
    }
}

在你的情况下,如果你需要捕获参数,也许将两者结合起来,所以如果有参数,有一个控制器可以捕获它并重定向到正确的 url(我对你的控制器的改进上面),然后是捕获新 url 并像我最后一个示例那样创建应用程序的路由。

或者,您最后只需使用我的示例,保持 url 不变并通过重定向在 Angular 中处理它。