使用参数

时间:2016-04-15 09:07:02

标签: asp.net-mvc angular angular2-routing

我正在尝试从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>

然后我引导应用程序

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}");
   }
}

由于我一次只在一个页面上迁移旧网站,因此我们的想法是在Action1, Action2上执行操作AppController等,并从旧版网页链接到这些操作。

1 个答案:

答案 0 :(得分:1)

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

你说你想要路线

/Action1/:param1/:param2

要路由但是给它

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

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

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 untipd并通过重定向在Angular中处理它。