【问题标题】:Angular 6 app in .NET MVC 5, angular routing doesn't work.NET MVC 5 中的 Angular 6 应用程序,角度路由不起作用
【发布时间】:2019-02-02 09:51:49
【问题描述】:

我在现有的 .NET MVC 5 应用程序中嵌入了一个 Angular 6 应用程序。我在 MVC 应用程序 (RouteConfig.cs) 中添加了一个指向 Home/Index 的后备路由,因此“未知”路由将传递给 Angular 应用程序的路由器模块 (app.routes.ts)。 Angular 应用的路由似乎没有触发,与路径关联的组件没有加载。

IDE 是 Visual Studio 2017 Enterprise 15.6.7,MVC 应用程序是标准 .NET Web 应用程序(不是 .NET Core),MVC 5.2.3.0; Node.js 8.11.3、npm 6.3.0、Typescript 2.9.2、Angular CLI 6.0.8、Angular 6.0.3;引导程序 3.3.7,jQuery 3.3.1;操作系统:Win 10 x64。

MVC 应用的 RouteConfig.cs 如下;包罗万象的路线在底部。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace Ang2Mvc5_0
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "mvc",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

            // This is a catch-all for when no other routes match the request; let the Angular 2 router take care of it...
            routes.MapRoute(
                name: "default",
                url: "{*url}",
                defaults: new { controller = "Home", action = "Index" } // The view that bootstraps Angular 2 app
            );
        }
    }
}

当我创建 Angular 应用程序(使用 CLI)时,Typescript 的 package.json 条目默认为 2.7.2; package.json 在下面,ngf-bootstrap 条目是特定于 PluralSight 教程的。

我错过了什么吗?

{
    "name": "temp-app",
    "version": "0.0.0",
    "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e"
    },
    "private": true,
    "dependencies": {
        "@angular/animations": "^6.0.3",
        "@angular/common": "^6.0.3",
        "@angular/compiler": "^6.0.3",
        "@angular/core": "^6.0.3",
        "@angular/forms": "^6.0.3",
        "@angular/http": "^6.0.3",
        "@angular/platform-browser": "^6.0.3",
        "@angular/platform-browser-dynamic": "^6.0.3",
        "@angular/router": "^6.0.3",
        "core-js": "^2.5.4",
        "ngf-bootstrap": "0.0.5",
        "rxjs": "^6.0.0",
        "toastr": "^2.1.4",
        "zone.js": "^0.8.26"
    },
    "devDependencies": {
        "@angular-devkit/build-angular": "~0.6.8",
        "@angular/cli": "~6.0.8",
        "@angular/compiler-cli": "^6.0.3",
        "@angular/language-service": "^6.0.3",
        "@types/jasmine": "~2.8.6",
        "@types/jasminewd2": "~2.0.3",
        "@types/node": "~8.9.4",
        "codelyzer": "~4.2.1",
        "jasmine-core": "~2.99.1",
        "jasmine-spec-reporter": "~4.2.1",
        "karma": "~1.7.1",
        "karma-chrome-launcher": "~2.2.0",
        "karma-coverage-istanbul-reporter": "~2.0.0",
        "karma-jasmine": "~1.1.1",
        "karma-jasmine-html-reporter": "^0.2.2",
        "protractor": "^5.4.0",
        "ts-node": "~5.0.1",
        "tslint": "~5.9.1",
        "typescript": "~2.7.2"
    }
}

app.routes.ts 在下面;这真的很简单,到目前为止,我还没有在应用程序开发方面取得很大进展。

import { NgModule } from '@angular/core'
import { Routes, RouterModule } from '@angular/router'

import { EventsListComponent } from './events/events-list.component'
import { EventDetailsComponent } from './events/event-details/event-details.component'

const routes: Routes = [
    {
        path: 'events',
        component: EventsListComponent
    },
    {
        path: 'events/:id',
        component: EventDetailsComponent
    },
    {
        path: '',
        redirectTo: '/events'
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routes, { enableTracing: true })],
    exports: [RouterModule]
})

export class AppRoutingModule {
}

EventsAppModule 在下面;注意@第 16 行,我已经导入了 AppRoutingModule (app.routes.ts),我可以评论这行来禁用路由。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { EventsAppComponent } from './events-app.component';
import { EventsListComponent } from './events/events-list.component';
import { EventThumbnailComponent } from './events/event-thumbnail.component';
import { EventDetailsComponent } from './events/event-details/event-details.component';
import { NavBarComponent } from './nav/navbar.component';
import { EventService } from './events/shared/event.service';
import { ToastrService } from './common/toastr.service';
import { AppRoutingModule } from './app.routes';

@NgModule({
    imports: [
        BrowserModule
        , AppRoutingModule
    ],
    declarations: [
        EventsAppComponent,
        EventsListComponent,
        EventThumbnailComponent,
        EventDetailsComponent,
        NavBarComponent
    ],
    providers: [
        EventService,
        ToastrService
    ],
    bootstrap: [EventsAppComponent]
})

export class EventsAppModule { }

如前所述,当尝试使用路由时,在应用程序的主组件/页面中使用 <router-outlet></router-outlet> 标记时,EventsListComponent 不会加载(我得到一个空白页面)。如果我从应用程序的模块中注释 AppRoutingModule 并切换到应用程序主组件中的 <events-list></events-list> 标记,则 EventsListComponent 加载正常(它显示事件列表,每个事件都封装在 EventThumbnailComponent 中)。

另外,当我运行时它不会加载http://localhost:39420/events;它默认为 root,例如 localhost:39420/ ...如果我在 url 中输入“/events”,我不会收到错误,只是一个空白页。如果我尝试使用 localhost:39420/events/1 ...再次获取 EventDetailsComponent,它只会呈现一个空白页面。

【问题讨论】:

  • redirectTo: 'events' 应该是redirectTo: '/events'
  • 谢谢,好点(已修复)。但是没有解决主要问题?
  • 您尝试再次导航到的网址是什么?

标签: asp.net-mvc angular typescript model-view-controller routing


【解决方案1】:

因此,当没有其他路由与请求匹配时,您必须捕获所有内容,以便 Angular 可以处理它。

// This is a catch-all for when no other routes match the request; let the Angular 2 router take care of it...
            routes.MapRoute(
                name: "default",
                url: "{*url}",
                defaults: new { controller = "Home", action = "Index" } // The view that bootstraps Angular 2 app
            );

您需要删除默认设置,使其看起来像这样。并且不要为角度创建控制器/视图。

// This is a catch-all for when no other routes match the request; let the Angular 2 router take care of it...
            routes.MapRoute(
                name: "default",
                url: "{*url}",// you don't need a view
            );

运行命令后

ng build --prod

将 dist 文件复制到带有根目录的 ex(myangularapp) 目录中 你的 mvc 应用程序的目录。您将需要更改基本标签 href 属性所以运行

ng build --prod --base-href=/myangularapp/

然后您可以将 web.config 文件添加到保存 Angular 文件 (myangularapp) 的目录中。示例如下。

<?xml version="1.0"?>
<configuration>
  <system.web></system.web>
  <system.webServer>
    <rewrite>
      <rules>
        <!--Redirect selected traffic to index -->
        <rule name="Index Rule" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          </conditions>
          <action type="Rewrite" url="index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

【讨论】:

    【解决方案2】:

    redirectTo 需要路由器导航到的确切路径。所以它需要一个/ 在您可能已经定义的路由路径之前。

    在您的路由配置中将redirectTo: 'events' 替换为redirectTo: '/events',它应该会正确加载EventsListComponent 组件。

    另外添加pathMatch: 'full' 到这条路线:

        {
            path: '',
            redirectTo: '/events',
            pathMatch: 'full'
        }
    

    这里有一个StackBlitz project 可以帮助您。

    【讨论】:

    • 谢谢,我希望事情就这么简单。不幸的是,修复后我仍然遇到相同的行为。此外,当我运行它时,它实际上并没有加载 /events;它默认为root,例如localhost:39420 ...而不是localhost:39420/events ...如果我输入它,我不会收到错误,只是一个空白页。如果我尝试获取 EventDetailsComponent,再次使用 localhost:39420/events/1 ...,它只会呈现一个空白页面。
    • 如果可能的话,你能创建一个 StackBlitz 吗?可能有几个问题。您可能忘记在 AppModule 中导入 AppRoutingModule。
    • 我编辑了问题,添加了我的 AppModule;如上所述(最后一段),AppRoutingModule 被导入;我已经切换评论它以确定路由是什么“破坏”了应用程序。
    • 感谢 StackBlitz,我试过了,一切正常。如果我只是在做一个独立的 Angular 应用程序(没有嵌入到 MVC 应用程序中),我会期待同样的行为——我之前已经做过,独立的 Angular 应用程序在我的开发环境中运行良好。这是关于将 Angular 应用程序添加到 .NET MVC 应用程序的事情,MVC 应用程序想要处理每个回发的路由。无论出于何种原因,似乎包罗万象的路由都没有将请求传递给 Angular 路由;看来Angular路由只是没有触发。我什至不确定如何诊断它。
    • 我的错,我错过了你的一条建议:将 pathMatch: 'full' 添加到默认(空)路由有很大帮助。我的路由问题仍未完全解决,但您的回答很有帮助。
    猜你喜欢
    • 2017-11-08
    • 2016-05-17
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 2018-10-04
    • 2017-06-22
    相关资源
    最近更新 更多